package com.vca.service.service.Impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.vca.common.constants.Constants;
import com.vca.common.constants.CouponConstants;
import com.vca.common.constants.OrderRedisConstans;
import com.vca.common.constants.SysGroupDataConstants;
import com.vca.common.exception.ExceptionCodeEnum;
import com.vca.common.exception.VcaException;
import com.vca.common.model.cat.StoreCart;
import com.vca.common.model.category.Category;
import com.vca.common.model.course.Course;
import com.vca.common.model.course.CoursePackage;
import com.vca.common.model.course.CourseScheduling;
import com.vca.common.model.exhibition.Exhibition;
import com.vca.common.model.exhibition.ExhibitionScheduling;
import com.vca.common.model.order.StoreOrder;
import com.vca.common.model.order.StoreOrderInfo;
import com.vca.common.model.order.StoreOrderStatus;
import com.vca.common.model.sms.SmsTemplate;
import com.vca.common.model.system.SystemAdmin;
import com.vca.common.model.system.SystemNotification;
import com.vca.common.model.talk.Talk;
import com.vca.common.model.talk.TalkScheduling;
import com.vca.common.model.user.User;
import com.vca.common.model.user.UserAddress;
import com.vca.common.model.user.UserCard;
import com.vca.common.model.user.UserToken;
import com.vca.common.model.vca_product.VcaProduct;
import com.vca.common.model.vca_product.VcaProductAttrValue;
import com.vca.common.page.CommonPage;
import com.vca.common.request.*;
import com.vca.common.response.*;
import com.vca.common.utils.*;
import com.vca.common.vo.*;
import com.vca.service.dao.order.StoreOrderDao;
import com.vca.service.service.*;
import jodd.util.StringUtil;
import lombok.val;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author chenbing
 * @date 2022/11/21   16:51
 */
@Service
public class VcaOrderServiceImpl extends ServiceImpl<StoreOrderDao, StoreOrder> implements VcaOrderService {

    private static final Logger logger = LoggerFactory.getLogger(VcaOrderServiceImpl.class);

    @Resource
    private StoreOrderDao dao;

    @Autowired
    private StoreOrderInfoService storeOrderInfoService;

    @Autowired
    private SystemNotificationService systemNotificationService;

    @Autowired
    private OrderPayService orderPayService;

    @Autowired
    private EmailTemplateService emailTemplateService;

    @Autowired
    private SmsTemplateService smsTemplateService;

    @Autowired
    private SmsService smsService;

    @Autowired
    private StoreOrderStatusService storeOrderStatusService;

    @Autowired
    private UserService userService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private CourseService courseService;

    @Autowired
    private CourseSchedulingService courseSchedulingService;

    @Autowired
    private SystemGroupDataService systemGroupDataService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Autowired
    private CoursePackageService coursePackageService;

    @Autowired
    private TalkService talkService;

    @Autowired
    private TalkSchedulingService talkSchedulingService;

    @Autowired
    private ExhibitionService exhibitionService;

    @Autowired
    private ExhibitionSchedulingService exhibitionSchedulingService;

    @Autowired
    private VcaProductService vcaProductService;

    @Autowired
    private VcaProductAttrValueService vcaProductAttrValueService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private StoreCartService cartService;

    @Autowired
    private UserCardService userCardService;

    @Autowired
    private UserAddressService userAddressService;

    @Autowired
    private UserTokenService userTokenService;

    @Autowired
    private TemplateMessageService templateMessageService;

    /**
     * @Description:预下单
     * @Author: chenBing
     * @Date: 2022/11/21
     */
    @Override
    public MyRecord proOrderCommon(String language,PreOrderCommonRequest request) {
        MyRecord myRecord = new MyRecord();
        User info = userService.getInfo();
        if (info == null) {
            throw new VcaException(ExceptionCodeEnum.UNAUTHORIZED.getMessage());
        }
        switch (request.getPreOrderType()) {
            //购物车只能添加商品，所以排除其他类型
            case "shoppingCart":
                myRecord = handleTypeShoppingCart(language,request, info);
                break;
            case "buyNow":
                myRecord = handleTypeBuyNow(language,request, info);
                break;
            case "again":
                break;
            default:
                break;
        }
        return myRecord;
    }

    /**
     * @param preOrderNo 预下单订单号
     * @Description:加载预下单
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    @Override
    public PreOrderCommonResponse loadPreCommon(String language,String preOrderNo) {
        String key = "user_course_order:" + preOrderNo;
        boolean exists = redisUtil.exists(key);
        if (!exists) {
            if("en".equals(language)){
                throw new VcaException("Pre-order does not exist");
            }else{
                throw new VcaException("预下单订单不存在");
            }
        }
        String preOrderCommonVoString = redisUtil.get(key).toString();
        PreOrderCommonVo preOrderCommonVo = JSONObject.parseObject(preOrderCommonVoString, PreOrderCommonVo.class);
        PreOrderCommonResponse preOrderCommonResponse = new PreOrderCommonResponse();
        preOrderCommonResponse.setPreOrderCommonVo(preOrderCommonVo);
        System.out.println(preOrderCommonVo+"=========");
        if("en".equals(language)){
            PreOrderCommonVo.CourseInfoDetail courseInfoDetail = preOrderCommonVo.getEventInfoDetail();
            List<PreOrderCommonVo.PreOrderProductDetail> productDetail = preOrderCommonVo.getProductDetail();
            if(productDetail != null){
                for (PreOrderCommonVo.PreOrderProductDetail preOrderProductDetail : productDetail) {
                    if(preOrderProductDetail.getNameEn() != null && !preOrderProductDetail.getNameEn().isEmpty()){
                        preOrderProductDetail.setName(preOrderProductDetail.getNameEn());
                    }

                    if(preOrderProductDetail.getIntroductionEn() != null && !preOrderProductDetail.getIntroductionEn().isEmpty()){
                        preOrderProductDetail.setIntroduction(preOrderProductDetail.getIntroductionEn());
                    }

                    if(preOrderProductDetail.getTypeEn() != null && !preOrderProductDetail.getTypeEn().isEmpty()){
                        preOrderProductDetail.setType(preOrderProductDetail.getTypeEn());
                    }

                    if(preOrderProductDetail.getSkuEn() != null && !preOrderProductDetail.getSkuEn().isEmpty()){
                        preOrderProductDetail.setSku(preOrderProductDetail.getSkuEn());
                    }
                }
            }

            if(courseInfoDetail != null){
                if(courseInfoDetail.getNameEn() != null && !courseInfoDetail.getNameEn().isEmpty()){
                    courseInfoDetail.setName(courseInfoDetail.getNameEn());
                }

                if(courseInfoDetail.getTypeNameEn() != null && !courseInfoDetail.getTypeNameEn().isEmpty()){
                    courseInfoDetail.setTypeName(courseInfoDetail.getTypeNameEn());
                }

                for (PreOrderCommonVo.CourseInfoDetail.Scheduling s : courseInfoDetail.getSchedulings()) {
                    if(s.getLanguageEn() != null && !s.getLanguageEn().isEmpty()){
                        s.setLanguage(s.getLanguageEn());
                    }
                    if(s.getCourseNameEn() != null && !s.getCourseNameEn().isEmpty()){
                        s.setCourseName(s.getCourseNameEn());
                    }
                    if(s.getCourseAddressEn() != null && !s.getCourseAddressEn().isEmpty()){
                        s.setCourseAddress(s.getCourseAddressEn());
                    }
                }
            }
        }
        if (preOrderCommonVo.getType() == 3) {
            System.out.println("1111111111");
            ExhibitionVo exhibitionVo = exhibitionService.info(language,preOrderCommonVo.getEventInfoDetail().getMainId());
            List<CourseAboutResponse> publicationRecommendations = exhibitionVo.getPublicationRecommendations();
            publicationRecommendations.forEach(publication -> {
                List<VcaProductAttrValue> attrValueList = vcaProductAttrValueService.list(new LambdaQueryWrapper<VcaProductAttrValue>().eq(VcaProductAttrValue::getProductId, publication.getAboutId()));
                publication.setAttValueId(attrValueList.get(0).getId());
            });
            preOrderCommonResponse.setPublicationRecommendations(exhibitionVo.getPublicationRecommendations());
        }
        return preOrderCommonResponse;
    }

    /**
     * @Description:计算订单价格
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    @Override
    public ComputedOrderCommonPriceResponse computedCommonPrice(String language,ComputedOrderCommonPriceRequest request) {
        String key = "user_course_order:" + request.getPreOrderNo();
        boolean exists = redisUtil.exists(key);
        if (!exists) {
            if("en".equals(language)){
                throw new VcaException("预下单订单不存在");
            }else{
                throw new VcaException("预下单订单不存在");
            }
        }
        String preOrderCommonVoString = redisUtil.get(key).toString();
        PreOrderCommonVo preOrderCommonVo = JSONObject.parseObject(preOrderCommonVoString, PreOrderCommonVo.class);
        User user = userService.getInfoException();
        return computedCommonPrice(language,preOrderCommonVo, request, user);
    }

    /**
     * @Description:创建订单
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    @Override
    public MyRecord createCommonOrder(String language,CreateCommonOrderRequest request) {
        User user = userService.getInfoException();
        String key = "user_course_order:" + request.getPreOrderNo();
        boolean exists = redisUtil.exists(key);
        if (!exists) {
            if("en".equals(language)){
                throw new VcaException("Pre-order does not exist");
            }else{
                throw new VcaException("预下单订单不存在");
            }
        }
        MyRecord myRecord = new MyRecord();
        String preOrderCommonVoString = redisUtil.get(key).toString();
        PreOrderCommonVo preOrderCommonVo = JSONObject.parseObject(preOrderCommonVoString, PreOrderCommonVo.class);
        System.out.println(preOrderCommonVoString+"^^^^^^^^^"+key);
        switch (preOrderCommonVo.getPreOrderType()) {
            case "shoppingCart":
                myRecord = createOrderShopping(language,request, preOrderCommonVo, user, key);
                break;
            case "buyNow":
                myRecord = createOrderCourse(language,request, preOrderCommonVo, user, key);
                break;
            default:
                break;
        }
        return myRecord;
    }

    /**
     * @Description:创建课程/讲座/展览/套课订单
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private MyRecord createOrderCourse(String language,CreateCommonOrderRequest request, PreOrderCommonVo preOrderCommonVo, User user, String key) {
        MyRecord myRecord = new MyRecord();
        // TODO: 2022/11/23 校验库存
        switch (preOrderCommonVo.getType()) {
            // TODO: 2022/11/22 课程
            case 0:
                Course course = courseService.getById(preOrderCommonVo.getEventInfoDetail().getMainId());
                myRecord = verifyAndCreateOrderOfCourse(language,request, preOrderCommonVo, user, course, key);
                break;
            // TODO: 2022/11/22 套课
            case 1:
                CoursePackage coursePackage = coursePackageService.getById(preOrderCommonVo.getEventInfoDetail().getMainId());
                myRecord = verifyCoursePackage(language,request, preOrderCommonVo, user, coursePackage, key);
                break;
            // TODO: 2022/11/22 讲座
            case 2:
                Talk talk = talkService.getById(preOrderCommonVo.getEventInfoDetail().getMainId());
                myRecord = verifyTalk(language,request, preOrderCommonVo, user, talk, key);
                break;
            // TODO: 2022/11/22 展览
            case 3:
                Exhibition exhibition = exhibitionService.getById(preOrderCommonVo.getEventInfoDetail().getMainId());
                myRecord = verifyExhibition(language,request, preOrderCommonVo, user, exhibition, key);
                break;
            // TODO: 2022/11/22 商品
            case 4:
                myRecord = createOrderShopping(language,request, preOrderCommonVo, user, key);
                break;
            default:
                break;
        }
        return myRecord;
    }

    /**
     * @Description:创建展览订单校验
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private MyRecord verifyExhibition(String language,CreateCommonOrderRequest request, PreOrderCommonVo preOrderCommonVo, User user, Exhibition exhibition, String key) {
        if (exhibition == null) {
            if("en".equals(language)){
                throw new VcaException("No current exhibition found");
            }else{
                throw new VcaException("未查询到当前展览");
            }
        }
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = preOrderCommonVo.getEventInfoDetail();
        ExhibitionScheduling exhibitionScheduling = exhibitionSchedulingService.getById(courseInfoDetail.getSchedulings().get(0).getScheduleId());
        if (exhibitionScheduling == null) {
            if("en".equals(language)){
                throw new VcaException("To query the current exhibition schedule");
            }else{
                throw new VcaException("为查询到当前展览排期");
            }
        }
        if (exhibitionScheduling.getQuota() <= 0) {
            if("en".equals(language)){
                throw new VcaException("The current reservation is full");
            }else{
                throw new VcaException("当前预约人数已满");
            }
        }
        if (exhibitionScheduling.getStatus() == 0) {
            if("en".equals(language)){
                throw new VcaException("The current exhibition schedule is not open for booking");
            }else{
                throw new VcaException("当前展览排期未开启预约");
            }
        }
        //TODO：获取展览提前停止预约时间
        Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.EXHIBITION_END_ORDER_TIME));
        Date schedulingDate = DateUtil.strToDate(exhibitionScheduling.getSchedulingDate() + " " + exhibitionScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
        DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
        long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
        if (between >= 0) {
            if("en".equals(language)){
                throw new VcaException("Exhibition stop booking");
            }else{
                throw new VcaException("展览停止预约");
            }
        }
        if (exhibitionScheduling.getQuota() < request.getCourseComputedPriceDetail().getAppointmentsCount()) {
            if("en".equals(language)){
                throw new VcaException("There are not enough seats left. Please re-select");
            }else{
                throw new VcaException("剩余席位不足，请重新选择");
            }
        }
        return generateOrder(language,request, user, preOrderCommonVo, key, exhibition.getCover(), Constants.ORDER_TYPE_EXHIBITION);
    }

    /**
     * @Description:创建讲座订单校验
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private MyRecord verifyTalk(String language,CreateCommonOrderRequest request, PreOrderCommonVo preOrderCommonVo, User user, Talk talk, String key) {
        if (talk == null) {
            if("en".equals(language)){
                throw new VcaException("No current lecture found");
            }else{
                throw new VcaException("未查询到当前讲座");
            }
        }
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = preOrderCommonVo.getEventInfoDetail();
        TalkScheduling talkScheduling = talkSchedulingService.getById(courseInfoDetail.getSchedulings().get(0).getScheduleId());
        if (talkScheduling == null) {
            if("en".equals(language)){
                throw new VcaException("The current lecture schedule is not found");
            }else{
                throw new VcaException("未查询到当前讲座排期");
            }
        }
        if (talkScheduling.getQuota() <= 0) {
            if("en".equals(language)){
                throw new VcaException("The current reservation is full");
            }else{
                throw new VcaException("当前预约人数已满");
            }
        }
        if (talkScheduling.getStatus() == 0) {
            if("en".equals(language)){
                throw new VcaException("The current lecture schedule is not open");
            }else{
                throw new VcaException("当前讲座排期未开启预约");
            }
        }
        //TODO：获取讲座提前停止预约时间
        Integer courseEndOrderTimeHour = 0;
        if (talk.getTalkType() == 1) {
            courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.TALK_END_ORDER_TIME));
            Date schedulingDate = DateUtil.strToDate(talkScheduling.getSchedulingDate() + " " + talkScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
            DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
            long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
            if (between >= 0) {
                if("en".equals(language)){
                    throw new VcaException("The lecture has closed for reservation");
                }else{
                    throw new VcaException("讲座已截止预约");
                }
            }
        }
        if (talk.getTalkType() == 2) {
            courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.ONLINE_TALK_END_ORDER_TIME));
        }
        if (talkScheduling.getQuota() < request.getCourseComputedPriceDetail().getAppointmentsCount()) {
            if("en".equals(language)){
                throw new VcaException("There are not enough seats left. Please re-select");
            }else{
                throw new VcaException("剩余席位不足，请重新选择");
            }
        }
        return generateOrder(language,request, user, preOrderCommonVo, key, talk.getCoverImage(), Constants.ORDER_TYPE_TALK);
    }

    /**
     * @Description:创建套课订单校验
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private MyRecord verifyCoursePackage(String language,CreateCommonOrderRequest request, PreOrderCommonVo preOrderCommonVo, User user, CoursePackage coursePackage, String key) {
        if (coursePackage == null) {
            if("en".equals(language)){
                throw new VcaException("The current suite is not found");
            }else{
                throw new VcaException("未查询到当前套课");
            }
        }
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = preOrderCommonVo.getEventInfoDetail();
        CreateCommonOrderRequest.CourseComputedPriceDetail courseComputedPriceDetail = request.getCourseComputedPriceDetail();
        List<PreOrderCommonVo.CourseInfoDetail.Scheduling> schedulings = courseInfoDetail.getSchedulings();
        schedulings.forEach(scheduling -> {
            CourseScheduling courseScheduling = courseSchedulingService.getById(scheduling.getScheduleId());
            if (courseScheduling == null) {
                if("en".equals(language)){
                    throw new VcaException("The current course schedule is not found");
                }else{
                    throw new VcaException("未查询到当前套课排期");
                }
            }
            if (!courseScheduling.getStatus()) {
                if("en".equals(language)){
                    throw new VcaException("This schedule package is not open for booking");
                }else{
                    throw new VcaException("该排期套课未开启预约");
                }
            }
            //TODO：获取课程提前停止预约时间
            Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.COURSE_END_ORDER_TIME));
            Date schedulingDate = DateUtil.strToDate(courseScheduling.getSchedulingDate() + " " + courseScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
            DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
            long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
            if (between >= 0) {
                if("en".equals(language)){
                    throw new VcaException("Classes are no longer reserved");
                }else{
                    throw new VcaException("套课已停止预约");
                }
            }
            // TODO: 2022/11/23 外部预约
            if (courseScheduling.getExternalLimit() <= 0) {
                if("en".equals(language)){
                    throw new VcaException("External reserved seats are full");
                }else{
                    throw new VcaException("外部预约席位已满");
                }
            }
            if (courseScheduling.getExternalLimit() < request.getCourseComputedPriceDetail().getAppointmentsCount()) {
                if("en".equals(language)){
                    throw new VcaException("There are not enough seats left. Please re-select");
                }else{
                    throw new VcaException("剩余席位不足，请重新选择");
                }
            }
        });
        return generateOrder(language,request, user, preOrderCommonVo, key, coursePackage.getCoverImage(), Constants.ORDER_TYPE_PACKAGE);
    }

    /**
     * @Description:创建课程订单校验
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private MyRecord verifyAndCreateOrderOfCourse(String language,CreateCommonOrderRequest request, PreOrderCommonVo preOrderCommonVo, User user, Course course, String key) {
        if (course == null) {
            if("en".equals(language)){
                throw new VcaException("The current course is not found");
            }else{
                throw new VcaException("未查询到当前课程");
            }

        }
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = preOrderCommonVo.getEventInfoDetail();

        CreateCommonOrderRequest.CourseComputedPriceDetail courseComputedPriceDetail = request.getCourseComputedPriceDetail();
        CourseScheduling courseScheduling = courseSchedulingService.getById(courseInfoDetail.getSchedulings().get(0).getScheduleId());
        if (courseScheduling == null) {
            if("en".equals(language)){
                throw new VcaException("The current course is not found");
            }else{
                throw new VcaException("未查询到当前课程");
            }
        }
        if (!courseScheduling.getStatus()) {
            if("en".equals(language)){
                throw new VcaException("This scheduled course is not open for booking");
            }else{
                throw new VcaException("该排期课程未开启预约");
            }
        }
        //TODO：获取课程提前停止预约时间
        Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.COURSE_END_ORDER_TIME));
        Date schedulingDate = DateUtil.strToDate(courseScheduling.getSchedulingDate() + " " + courseScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
        DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
        long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
        if (between >= 0) {
            if("en".equals(language)){
                throw new VcaException("Class stop booking");
            }else{
                throw new VcaException("课程停止预约");
            }
        }
        // TODO: 2022/11/23 外部预约
        if (courseScheduling.getExternalLimit() <= 0) {
            if("en".equals(language)){
                throw new VcaException("External reserved seats are full");
            }else{
                throw new VcaException("外部预约席位已满");
            }
        }
        if (courseScheduling.getExternalLimit() < courseComputedPriceDetail.getAppointmentsCount()) {
            if("en".equals(language)){
                throw new VcaException("There are not enough seats left. Please re-select");
            }else{
                throw new VcaException("剩余席位不足，请重新选择");
            }
        }
        return generateOrder(language,request, user, preOrderCommonVo, key, course.getCover(), Constants.ORDER_TYPE_COURSE);
    }

    /**
     * @Description:生成订单
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    public MyRecord generateOrder(String language,CreateCommonOrderRequest request, User user, PreOrderCommonVo preOrderCommonVo, String key, String image, Integer type) {
        List<CreateCommonOrderRequest.ShopComputedPriceDetail> shopComputedPriceDetails = request.getShopComputedPriceDetails();
        CreateCommonOrderRequest.CourseComputedPriceDetail courseComputedPriceDetail = request.getCourseComputedPriceDetail();
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = preOrderCommonVo.getEventInfoDetail();

        ComputedOrderCommonPriceRequest computedOrderCommonPriceRequest = new ComputedOrderCommonPriceRequest();
        handleCreateCommonOrderRequest(request, computedOrderCommonPriceRequest, "no_shopping_cart");
        List<CreateCommonOrderRequest.UserInformation> giveAwayToOthersMap = courseComputedPriceDetail.getGiveAwayToOthersMap();
        if (courseComputedPriceDetail.getAppointmentsCount() > giveAwayToOthersMap.size()) {
            int num = courseComputedPriceDetail.getAppointmentsCount() - giveAwayToOthersMap.size();
            for (int i = 0; i < num; i++) {
                CreateCommonOrderRequest.UserInformation userInformation = new CreateCommonOrderRequest.UserInformation();
                userInformation.setAppointmentOfClassStaff(user.getNickname());
                userInformation.setAppointmentPhoneNumber(user.getPhone());
                giveAwayToOthersMap.add(userInformation);
            }
        }
        // TODO: 2022/11/14 获得礼品卡信息
        UserCard userCard = new UserCard();
        if (ObjectUtil.isNotNull(courseComputedPriceDetail.getCardId())) {
            userCard = userCardService.getById(courseComputedPriceDetail.getCardId());
        }
        List<SaveOrderVo> saveOrderVos = new ArrayList<>();
        List<StoreOrder> storeOrders = new ArrayList<>();
        int i = 0;
        for (CreateCommonOrderRequest.UserInformation map : giveAwayToOthersMap) {
            // TODO: 2022/11/11 生成订单号
            String mainOrderNo = VcaUtil.getOrderNo("order");
            SaveOrderVo saveOrderVo = new SaveOrderVo();
            i++;
            // TODO: 2022/11/11 创建订单 storeOrder
            StoreOrder storeOrder = new StoreOrder();
            storeOrder.setUid(user.getUid());
            storeOrder.setOrderId(mainOrderNo);
            storeOrder.setRealName(user.getNickname());
            storeOrder.setUserPhone(user.getPhone());
            storeOrder.setTotalNum(1);
            if (ObjectUtil.isNotNull(courseComputedPriceDetail.getCardId()) && i != 1) {
                storeOrder.setCouponId(0);
                storeOrder.setCouponPrice(BigDecimal.ZERO);
            } else {
                if (ObjectUtil.isNotNull(courseComputedPriceDetail.getCardId())) {
                    storeOrder.setCouponId(courseComputedPriceDetail.getCardId());
                    storeOrder.setCouponPrice(userCard.getFaceValue());
                }
            }
            storeOrder.setTotalPrice(courseInfoDetail.getPrice());
            storeOrder.setProTotalPrice(courseInfoDetail.getPrice());
            storeOrder.setPayPrice(courseInfoDetail.getPrice());
            storeOrder.setPayType(Constants.PAY_TYPE_WE_CHAT);
            storeOrder.setCreateTime(DateUtil.nowDateTime());
            storeOrder.setStatus(0);
            storeOrder.setPaid(false);
            storeOrder.setType(type);
            storeOrder.setBeforePayPrice(storeOrder.getPayPrice());
            List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
            for (PreOrderCommonVo.CourseInfoDetail.Scheduling s : courseInfoDetail.getSchedulings()) {
                // TODO: 2022/11/14 创建orderInfo订单详情
                // TODO: 2022/11/11 生成订单号
                String orderNo = VcaUtil.getOrderNo("order");
                StoreOrderInfo orderInfo = new StoreOrderInfo();

                System.out.println(courseInfoDetail+"------------");
                orderInfo.setInfo(JSON.toJSON(courseInfoDetail).toString());
                orderInfo.setOrderNo(mainOrderNo);
                orderInfo.setMerOrderNo(orderNo);
                orderInfo.setType(type);
                orderInfo.setMainId(courseInfoDetail.getMainId());
                orderInfo.setSchedulingId(s.getScheduleId());
                if (type == 1) {
                    orderInfo.setTaokeAboutCourseId(s.getCourseId());
                }
                orderInfo.setNameEn(courseInfoDetail.getNameEn());
                orderInfo.setName(courseInfoDetail.getName());
                orderInfo.setPrice(courseInfoDetail.getPrice());
                if (storeOrder.getType() == 1) {
                    orderInfo.setPrice(BigDecimal.ZERO.compareTo(orderInfo.getPrice()) < 0 ? orderInfo.getPrice().divide(BigDecimal.valueOf(courseInfoDetail.getSchedulings().size()), 2, RoundingMode.DOWN) : BigDecimal.ZERO);
                }
                orderInfo.setPayNum(1);
                orderInfo.setWeight(BigDecimal.ZERO);
                orderInfo.setVolume(BigDecimal.ZERO);
                orderInfo.setSchedulingDate(s.getSchedulingDate());
                orderInfo.setSchedulingStartTime(s.getSchedulingStartTime());
                orderInfo.setSchedulingEndTime(s.getSchedulingEndTime());
                orderInfo.setRefundStatus(0);
                if (ObjectUtil.isNotNull(courseComputedPriceDetail.getCardId()) && i == 1) {
                    orderInfo.setPayPrice(BigDecimal.ZERO);
                } else {
                    orderInfo.setPayPrice(orderInfo.getPrice().multiply(BigDecimal.valueOf(orderInfo.getPayNum())));
                }
                orderInfo.setBuyer(user.getUid());      //设置购买人
                User one = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getPhone, map.getAppointmentPhoneNumber()));
                if (one != null) {
                    orderInfo.setLecturer(one.getUid());
                    orderInfo.setLecturerEmail(ObjectUtil.isNotNull(one.getEmail()) ? one.getEmail() : null);
                }
                if (ObjectUtil.isNotNull(courseComputedPriceDetail.getCardId()) && i == 1) {
                    storeOrder.setPayPrice(storeOrder.getTotalPrice().subtract(userCard.getFaceValue()));
                    storeOrder.setBeforePayPrice(storeOrder.getPayPrice());
                }
                orderInfo.setLecturerName(map.getAppointmentOfClassStaff());
                orderInfo.setLecturerPhone(map.getAppointmentPhoneNumber());
                List<HashMap<String, Object>> mapList = new ArrayList<>();
                courseInfoDetail.getSchedulings().forEach(scheduling -> {
                    if("en".equals(language)){
                        mapList.add(scheduling.getCourseAddressEn());
                    }else{
                        mapList.add(scheduling.getCourseAddress());
                    }
                });
                orderInfo.setAddress(JSON.toJSONString(mapList));

                orderInfo.setLanguage(s.getLanguageEn());
                orderInfo.setLanguage(s.getLanguage());

                orderInfo.setImage(image);
                orderInfo.setStatus(0);
                storeOrderInfos.add(orderInfo);
            }
            saveOrderVo.setOrderInfoList(storeOrderInfos);
            saveOrderVo.setOrder(storeOrder);
            saveOrderVos.add(saveOrderVo);
        }
        // TODO: 2022/11/23 如果预约类型为展览时，判断是否携带的有商品
        List<StoreOrderInfo> orderInfoListShop = new ArrayList<>();
        // TODO: 2022/11/23 创建订单
        StoreOrder storeOrderShop = new StoreOrder();
        if (shopComputedPriceDetails != null) {
            if (type == 3 && shopComputedPriceDetails.size() > 0) {
                UserAddress userAddress = null;
                for (CreateCommonOrderRequest.ShopComputedPriceDetail shopItem : shopComputedPriceDetails) {
                    // TODO: 2022/11/23 校验商品库存
                    StoreOrderInfo orderInfo = verifyStockShop(language,shopItem, user, preOrderCommonVo, null, request.getAddressId());
                    UserAddress address = orderInfo.getUserAddress();
                    userAddress = new UserAddress();
                    BeanUtils.copyProperties(address, userAddress);
                    orderInfoListShop.add(orderInfo);
                }
                ComputedOrderCommonPriceResponse priceResponse = handleTypeShoppingCartComputedPrice(language,preOrderCommonVo, computedOrderCommonPriceRequest, user);
                storeOrderShop.setUid(user.getUid());
                // TODO: 2022/11/11 生成订单号
                String orderNo = VcaUtil.getOrderNo("order");
                storeOrderShop.setOrderId(orderNo);
                storeOrderShop.setRealName(ObjectUtil.isNotNull(userAddress) ? userAddress.getRealName() : ObjectUtil.isNull(user.getNickname()) ? null : user.getNickname());
                storeOrderShop.setUserPhone(ObjectUtil.isNotNull(userAddress) ? userAddress.getPhone() : ObjectUtil.isNull(user.getPhone()) ? null : user.getPhone());
                storeOrderShop.setUserAddress(ObjectUtil.isNotNull(userAddress) ? userAddress.getProvince() + " " + userAddress.getCity() + "" + userAddress.getDistrict() + "" + userAddress.getDetail() : null);

                storeOrderShop.setTotalNum(priceResponse.getCount());
                // TODO: 2022/11/23 需要支付的总金额=商品总价+邮费
                storeOrderShop.setTotalPrice(priceResponse.getPayTotalFree());
                storeOrderShop.setPayPrice(priceResponse.getPayFree());
                storeOrderShop.setPaid(false);
                storeOrderShop.setPayType(Constants.PAY_TYPE_WE_CHAT);
                storeOrderShop.setCreateTime(DateUtil.nowDateTime());
                storeOrderShop.setType(Constants.ORDER_TYPE_PRODUCT);
                storeOrderShop.setRefundStatus(0);
                storeOrderShop.setIsDel(false);
                storeOrderShop.setProTotalPrice(priceResponse.getPayTotalFree());
                storeOrderShop.setIsAlterPrice(false);
                // TODO: 2022/11/23 填充orderInfoList中的orderNo
                orderInfoListShop.forEach(orderInfo -> {
                    orderInfo.setOrderNo(orderNo);
                });
            }
        }
        List<String> orderNoList = new ArrayList<>();
        UserCard finalUserCard = userCard;
        Boolean execute = transactionTemplate.execute(e -> {
            saveOrderVos.forEach(saveOrderVo -> {
                StoreOrder order = saveOrderVo.getOrder();
                List<StoreOrderInfo> orderInfoList = saveOrderVo.getOrderInfoList();
                save(order);
                if (ObjectUtil.isNotNull(courseComputedPriceDetail.getCardId())) {
                    finalUserCard.setStutus(CouponConstants.STORE_COUPON_USER_STATUS_USED);
                    // TODO: 2023/1/28 添加礼品卡使用时间
                    finalUserCard.setUseTime(new Date());
                    userCardService.updateById(finalUserCard);
                }
                StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
                storeOrderStatus.setOid(order.getId());
                storeOrderStatus.setChangeType(Constants.ORDER_STATUS_CACHE_CREATE_ORDER);
                storeOrderStatus.setChangeMessage("订单生成");
                storeOrderStatus.setCreateTime(DateUtil.nowDateTime());
                //保存课程订单详情
                storeOrderInfoService.saveBatch(orderInfoList);
                storeOrderStatusService.save(storeOrderStatus);
                // 加入自动未支付自动取消队列
                redisUtil.lPush(OrderRedisConstans.ORDER_AUTO_CANCEL_KEY, order.getOrderId());
                orderNoList.add(order.getOrderId());
            });
            // TODO: 2022/11/23 当预约类型为展览类型时
            if (shopComputedPriceDetails != null) {
                if (type == 3 && shopComputedPriceDetails.size() > 0) {
                    StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
                    // TODO: 2022/11/23 保存storeOrder
                    save(storeOrderShop);
                    storeOrderStatus.setOid(storeOrderShop.getId());
                    storeOrderStatus.setChangeType(Constants.ORDER_STATUS_CACHE_CREATE_ORDER);
                    storeOrderStatus.setChangeMessage("订单生成");
                    storeOrderStatus.setCreateTime(DateUtil.nowDateTime());
                    // TODO: 2022/11/23 保存订单详情
                    storeOrderInfoService.saveBatch(orderInfoListShop);
                    // TODO: 2022/11/23 生成订单日志
                    storeOrderStatusService.save(storeOrderStatus);
                    // 加入自动未支付自动取消队列
                    redisUtil.lPush(OrderRedisConstans.ORDER_AUTO_CANCEL_KEY, storeOrderShop.getOrderId());
                    orderNoList.add(storeOrderShop.getOrderId());
                }
            }
            // TODO: 2022/12/16 扣减库存
            VcaProductStockVo vcaProductStockVo = deductionsStock(orderNoList);
            List<CourseScheduling> courseSchedulingList = vcaProductStockVo.getCourseSchedulingList();
            List<TalkScheduling> talkSchedulingList = vcaProductStockVo.getTalkSchedulingList();
            List<ExhibitionScheduling> exhibitionSchedulingList = vcaProductStockVo.getExhibitionSchedulingList();
            List<VcaProduct> vcaProducts = vcaProductStockVo.getVcaProducts();
            List<VcaProductAttrValue> vcaProductAttrValues = vcaProductStockVo.getVcaProductAttrValues();
            if (courseSchedulingList.size() > 0) {
                courseSchedulingService.updateBatchById(courseSchedulingList);
            }
            if (talkSchedulingList.size() > 0) {
                talkSchedulingService.updateBatchById(talkSchedulingList);
            }
            if (exhibitionSchedulingList.size() > 0) {
                exhibitionSchedulingService.updateBatchById(exhibitionSchedulingList);
            }
            if (vcaProducts.size() > 0) {
                vcaProductService.updateBatchById(vcaProducts);
            }
            if (vcaProductAttrValues.size() > 0) {
                vcaProductAttrValueService.updateBatchById(vcaProductAttrValues);
            }
            return Boolean.TRUE;
        });
        if (!execute) {
            if("en".equals(language)){
                throw new VcaException("Order generation failure");
            }else{
                throw new VcaException("订单生成失败");
            }
        }
        // 删除缓存订单
        if (redisUtil.exists(key)) {
            redisUtil.delete(key);
        }
        MyRecord record = new MyRecord();
        record.set("orderNo", orderNoList);
        return record;
    }

    /**
     * @Description:创建购物车订单
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private MyRecord createOrderShopping(String language,CreateCommonOrderRequest request, PreOrderCommonVo preOrderCommonVo, User user, String key) {
        // TODO: 2022/11/23 获取发货地址address
        UserAddress userAddress = null;
        // TODO: 2022/11/23 获取商品订单详情orderInfo和购物车订单计算价格结果
        ShopOrderVo shopOrderVo = getShopOrderVo(language,request, preOrderCommonVo, user);
        UserAddress address = shopOrderVo.getUserAddress();
        if (address != null) {
            userAddress = new UserAddress();
            BeanUtils.copyProperties(address, userAddress);
        }
        ComputedOrderCommonPriceResponse priceResponse = shopOrderVo.getPriceResponse();
        // TODO: 2022/11/23 创建订单
        List<StoreOrderInfo> orderInfoList = shopOrderVo.getOrderInfoList();
        StoreOrder storeOrder = new StoreOrder();
        if (shopOrderVo.getOrderInfoList().size() > 0) {
            storeOrder.setUid(user.getUid());
            //todo:生成主订单号
            String orderNo = VcaUtil.getOrderNo("order");
            storeOrder.setOrderId(orderNo);
            if (userAddress != null) {
                storeOrder.setRealName(ObjectUtil.isNotNull(userAddress.getRealName()) ? userAddress.getRealName() : ObjectUtil.isNull(user.getNickname()) ? null : user.getNickname());
                storeOrder.setUserPhone(ObjectUtil.isNotNull(userAddress.getPhone()) ? userAddress.getPhone() : ObjectUtil.isNull(user.getPhone()) ? null : user.getPhone());
                storeOrder.setUserAddress(ObjectUtil.isNotNull(userAddress) ? userAddress.getProvince() + " " + userAddress.getCity() + "" + userAddress.getDistrict() + "" + userAddress.getDetail() : null);
                storeOrder.setProvince(userAddress.getProvince());
                storeOrder.setCity(userAddress.getCity());
                storeOrder.setDistrict(userAddress.getDistrict());
                storeOrder.setDetail(userAddress.getDetail());
            } else {
                storeOrder.setRealName(ObjectUtil.isNull(user.getNickname()) ? null : user.getNickname());
                storeOrder.setUserPhone(ObjectUtil.isNull(user.getPhone()) ? null : user.getPhone());
                storeOrder.setUserAddress(null);
            }
            storeOrder.setTotalNum(shopOrderVo.getShopTotalCount());
            // TODO: 2022/11/23 需要支付的总金额=商品总价+邮费
            storeOrder.setTotalPrice(shopOrderVo.getShopTotalPrice());
            storeOrder.setProTotalPrice(shopOrderVo.getShopTotalPrice());
            storeOrder.setPayPrice(shopOrderVo.getShopTotalPrice());
            storeOrder.setPaid(false);
            storeOrder.setPayType(Constants.PAY_TYPE_WE_CHAT);
            storeOrder.setCreateTime(DateUtil.nowDateTime());
            storeOrder.setType(Constants.ORDER_TYPE_PRODUCT);
            storeOrder.setRefundStatus(0);
            storeOrder.setIsDel(false);
            storeOrder.setStatus(0);
            storeOrder.setBeforePayPrice(storeOrder.getPayPrice());
            storeOrder.setIsAlterPrice(false);
            // TODO: 2022/11/23 填充orderInfoList中的orderNo
            orderInfoList.forEach(orderInfo -> {
                orderInfo.setOrderNo(orderNo);
            });
        }
        System.out.println(storeOrder+"=========");
        List<StoreOrderInfo> orderCardInfoList = shopOrderVo.getOrderInfoCardList();
        StoreOrder storeOrderCard = new StoreOrder();
        if (shopOrderVo.getOrderInfoCardList().size() > 0) {
            storeOrderCard.setUid(user.getUid());
            String orderNo = VcaUtil.getOrderNo("order");
            storeOrderCard.setOrderId(orderNo);
            storeOrderCard.setRealName(ObjectUtil.isNotNull(userAddress) ? userAddress.getRealName() : ObjectUtil.isNull(user.getNickname()) ? null : user.getNickname());
            storeOrderCard.setUserPhone(ObjectUtil.isNotNull(userAddress) ? userAddress.getPhone() : ObjectUtil.isNull(user.getPhone()) ? null : user.getPhone());
            storeOrderCard.setUserAddress(ObjectUtil.isNotNull(userAddress) ? userAddress.getProvince() + " " + userAddress.getCity() + "" + userAddress.getDistrict() + "" + userAddress.getDetail() : null);
            storeOrderCard.setTotalNum(shopOrderVo.getCardTotalCount());
            // TODO: 2022/11/23 需要支付的总金额=商品总价+邮费
            storeOrderCard.setTotalPrice(shopOrderVo.getCardTotalPrice());
            storeOrderCard.setProTotalPrice(shopOrderVo.getCardTotalPrice());
            storeOrderCard.setPayPrice(shopOrderVo.getCardTotalPrice());
            storeOrderCard.setPaid(false);
            storeOrderCard.setPayType(Constants.PAY_TYPE_WE_CHAT);
            storeOrderCard.setCreateTime(DateUtil.nowDateTime());
            storeOrderCard.setType(Constants.ORDER_TYPE_PRODUCT);
            storeOrderCard.setRefundStatus(0);
            storeOrderCard.setIsDel(false);
            storeOrderCard.setStatus(0);
            storeOrderCard.setIsAlterPrice(false);
            storeOrderCard.setBeforePayPrice(storeOrderCard.getPayPrice());
            // TODO: 2022/11/23 填充orderInfoList中的orderNo
            orderCardInfoList.forEach(orderInfo -> {
                orderInfo.setOrderNo(orderNo);
            });
        }

        List<String> orderNoList = new ArrayList<>();
        Boolean execute = transactionTemplate.execute(e -> {
            List<StoreOrderStatus> storeOrderStatuses = new ArrayList<>();
            if (shopOrderVo.getOrderInfoList().size() > 0) {
                // TODO: 2022/11/23 保存storeOrder
                save(storeOrder);
                storeOrderInfoService.saveBatch(orderInfoList);
                StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
                storeOrderStatus.setOid(storeOrder.getId());
                storeOrderStatus.setChangeType(Constants.ORDER_STATUS_CACHE_CREATE_ORDER);
                storeOrderStatus.setChangeMessage("订单生成");
                storeOrderStatus.setCreateTime(DateUtil.nowDateTime());
                storeOrderStatuses.add(storeOrderStatus);
                // TODO: 2022/11/23 加入自动未支付自动取消队列
                redisUtil.lPush(OrderRedisConstans.ORDER_AUTO_CANCEL_KEY, storeOrder.getOrderId());
                orderNoList.add(storeOrder.getOrderId());
            }
            if (shopOrderVo.getOrderInfoCardList().size() > 0) {
                save(storeOrderCard);
                // TODO: 2022/11/23 保存订单详情
                storeOrderInfoService.saveBatch(orderCardInfoList);
                StoreOrderStatus storeOrderStatus1 = new StoreOrderStatus();
                storeOrderStatus1.setOid(storeOrderCard.getId());
                storeOrderStatus1.setChangeType(Constants.ORDER_STATUS_CACHE_CREATE_ORDER);
                storeOrderStatus1.setChangeMessage("订单生成");
                storeOrderStatus1.setCreateTime(DateUtil.nowDateTime());
                storeOrderStatuses.add(storeOrderStatus1);
                // TODO: 2022/11/23 加入自动未支付自动取消队列
                redisUtil.lPush(OrderRedisConstans.ORDER_AUTO_CANCEL_KEY, storeOrderCard.getOrderId());
                orderNoList.add(storeOrderCard.getOrderId());
            }
            // TODO: 2022/11/23 生成订单日志
            storeOrderStatusService.saveBatch(storeOrderStatuses);
            // TODO: 2022/12/16 扣减库存
            VcaProductStockVo vcaProductStockVo = deductionsStock(orderNoList);
            List<CourseScheduling> courseSchedulingList = vcaProductStockVo.getCourseSchedulingList();
            List<TalkScheduling> talkSchedulingList = vcaProductStockVo.getTalkSchedulingList();
            List<ExhibitionScheduling> exhibitionSchedulingList = vcaProductStockVo.getExhibitionSchedulingList();
            List<VcaProduct> vcaProducts = vcaProductStockVo.getVcaProducts();
            List<VcaProductAttrValue> vcaProductAttrValues = vcaProductStockVo.getVcaProductAttrValues();
            if (courseSchedulingList.size() > 0) {
                courseSchedulingService.updateBatchById(courseSchedulingList);
            }
            if (talkSchedulingList.size() > 0) {
                talkSchedulingService.updateBatchById(talkSchedulingList);
            }
            if (exhibitionSchedulingList.size() > 0) {
                exhibitionSchedulingService.updateBatchById(exhibitionSchedulingList);
            }
            if (vcaProducts.size() > 0) {
                vcaProductService.updateBatchById(vcaProducts);
            }
            if (vcaProductAttrValues.size() > 0) {
                vcaProductAttrValueService.updateBatchById(vcaProductAttrValues);
            }
            // 清除购物车数据
            if (CollUtil.isNotEmpty(preOrderCommonVo.getCartIdList())) {
                cartService.deleteCartByIds(preOrderCommonVo.getCartIdList());
            }
            return Boolean.TRUE;
        });
        if (!execute) {
            if("en".equals(language)){
                throw new VcaException("Order generation failure");
            }else{
                throw new VcaException("订单生成失败");
            }
        }
        // TODO: 2022/11/23 删除缓存订单
        if (redisUtil.exists(key)) {
            redisUtil.delete(key);
        }
        MyRecord record = new MyRecord();
        record.set("orderNo", orderNoList);
        return record;
    }

    private VcaProductStockVo deductionsStock(List<String> orderNoList) {
        // TODO: 2022/12/16 扣减库存
        List<StoreOrder> orderList = list(new LambdaQueryWrapper<StoreOrder>().in(StoreOrder::getOrderId, orderNoList));
        // TODO: 2022/12/7 判断订单类型
        List<CourseScheduling> courseSchedulingList = new ArrayList<>();
        List<TalkScheduling> talkSchedulingList = new ArrayList<>();
        List<ExhibitionScheduling> exhibitionSchedulingList = new ArrayList<>();
        List<VcaProduct> vcaProducts = new ArrayList<>();
        List<VcaProductAttrValue> vcaProductAttrValues = new ArrayList<>();
        for (StoreOrder order : orderList) {
            switch (order.getType()) {
                //0-课程订单
                case 0:
                    //1=套课订单
                case 1:
                    List<CourseScheduling> courseSchedulings = deductionsStockOfCourse(order);
                    courseSchedulings.forEach(courseScheduling -> {
                        courseSchedulingList.add(courseScheduling);
                    });
                    break;
                //2=讲座订单
                case 2:
                    List<TalkScheduling> talkSchedulings = deductionsStockOfTalk(order);
                    talkSchedulings.forEach(talkScheduling -> {
                        talkSchedulingList.add(talkScheduling);
                    });
                    break;
                //3=展览订单
                case 3:
                    List<ExhibitionScheduling> exhibitionSchedulings = deductionsStockOfExhibition(order);
                    exhibitionSchedulings.forEach(exhibitionScheduling -> {
                        exhibitionSchedulingList.add(exhibitionScheduling);
                    });
                    break;
                // 4=商品订单
                case 4:
                    VcaProductStockVo vcaProductStockVo1 = deductionsStockOfProduct(order);
                    vcaProductStockVo1.getVcaProducts().forEach(vcaProduct -> {
                        vcaProducts.add(vcaProduct);
                    });
                    vcaProductStockVo1.getVcaProductAttrValues().forEach(vcaProductAttrValue -> {
                        vcaProductAttrValues.add(vcaProductAttrValue);
                    });
                    break;
                default:
                    break;
            }
        }
        VcaProductStockVo vcaProductStockVo = new VcaProductStockVo();
        vcaProductStockVo.setCourseSchedulingList(courseSchedulingList);
        vcaProductStockVo.setExhibitionSchedulingList(exhibitionSchedulingList);
        vcaProductStockVo.setTalkSchedulingList(talkSchedulingList);
        vcaProductStockVo.setVcaProductAttrValues(vcaProductAttrValues);
        vcaProductStockVo.setVcaProducts(vcaProducts);
        return vcaProductStockVo;
    }

    /**
     * @Description:扣减展览库存
     * @author:chenbing
     * @date 2022/12/7 15:43
     */
    private List<ExhibitionScheduling> deductionsStockOfExhibition(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<ExhibitionScheduling> exhibitionSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            ExhibitionScheduling exhibitionScheduling = exhibitionSchedulingService.getOne(new LambdaQueryWrapper<ExhibitionScheduling>().eq(ExhibitionScheduling::getExhibitionId, orderInfo.getMainId()).eq(ExhibitionScheduling::getId, orderInfo.getSchedulingId()));
            exhibitionScheduling.setQuota(exhibitionScheduling.getQuota() > 0 ? exhibitionScheduling.getQuota() - orderInfo.getPayNum() : 0);
            exhibitionScheduling.setNumberOfAppointments(exhibitionScheduling.getNumberOfAppointments() + orderInfo.getPayNum());
            exhibitionSchedulings.add(exhibitionScheduling);
        });
        return exhibitionSchedulings;
    }

    /**
     * @Description:扣减讲座库存
     * @author:chenbing
     * @date 2022/12/7 15:21
     */
    private List<TalkScheduling> deductionsStockOfTalk(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<TalkScheduling> talkSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            TalkScheduling talkScheduling = talkSchedulingService.getOne(new LambdaQueryWrapper<TalkScheduling>().eq(TalkScheduling::getTalkId, orderInfo.getMainId()).eq(TalkScheduling::getId, orderInfo.getSchedulingId()));
            talkScheduling.setQuota(talkScheduling.getQuota() > 0 ? talkScheduling.getQuota() - orderInfo.getPayNum() : 0);
            talkScheduling.setNumberOfAppointments(talkScheduling.getNumberOfAppointments() + orderInfo.getPayNum());
            talkSchedulings.add(talkScheduling);
        });
        return talkSchedulings;
    }

    /**
     * @Description:扣减课程库存
     * @author:chenbing
     * @date 2022/12/7 15:14
     */
    private List<CourseScheduling> deductionsStockOfCourse(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<CourseScheduling> courseSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            LambdaQueryWrapper<CourseScheduling> lqw = new LambdaQueryWrapper<CourseScheduling>().eq(CourseScheduling::getId, orderInfo.getSchedulingId());
            if (Objects.equals(orderInfo.getType(), Constants.ORDER_TYPE_PACKAGE)) {
                lqw.eq(CourseScheduling::getCourseId, orderInfo.getTaokeAboutCourseId());
            } else {
                lqw.eq(CourseScheduling::getCourseId, orderInfo.getMainId());
            }
            CourseScheduling scheduling = courseSchedulingService.getOne(lqw);

            scheduling.setExternalLimit(scheduling.getExternalLimit() > 0 ? scheduling.getExternalLimit() - orderInfo.getPayNum() : 0);
            scheduling.setExternalAppointment(scheduling.getExternalAppointment() + orderInfo.getPayNum());
            courseSchedulings.add(scheduling);
        });
        return courseSchedulings;
    }

    /**
     * @Description:扣减商品库存（商品订单如果是礼品卡订单，那么就需要进行拆单）
     * @author:chenbing
     * @date 2022/12/7 15:00
     */
    private VcaProductStockVo deductionsStockOfProduct(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<VcaProduct> vcaProducts = new ArrayList<>();
        List<VcaProductAttrValue> vcaProductAttrValues = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            VcaProduct product = vcaProductService.getById(orderInfo.getProductId());
            product.setStock(product.getStock() - orderInfo.getPayNum());
            VcaProductAttrValue productAttrValue = vcaProductAttrValueService.getById(orderInfo.getAttrValueId());
            productAttrValue.setStock(productAttrValue.getStock() - orderInfo.getPayNum());
            vcaProducts.add(product);
            vcaProductAttrValues.add(productAttrValue);
        });
        VcaProductStockVo vcaProductStockVo = new VcaProductStockVo();
        vcaProductStockVo.setVcaProducts(vcaProducts);
        vcaProductStockVo.setVcaProductAttrValues(vcaProductAttrValues);
        return vcaProductStockVo;
    }

    /**
     * @Description:获取商品订单详情orderInfo和购物车订单计算价格结果
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private ShopOrderVo getShopOrderVo(String language,CreateCommonOrderRequest request, PreOrderCommonVo preOrderCommonVo, User user) {
        ShopOrderVo shopOrderVo = new ShopOrderVo();
        List<CreateCommonOrderRequest.ShopComputedPriceDetail> shopComputedPriceDetails = request.getShopComputedPriceDetails();
        ComputedOrderCommonPriceRequest computedOrderCommonPriceRequest = new ComputedOrderCommonPriceRequest();
        handleCreateCommonOrderRequest(request, computedOrderCommonPriceRequest, preOrderCommonVo.getPreOrderType());
        ComputedOrderCommonPriceResponse computedOrderCommonPriceResponse = handleTypeShoppingCartComputedPrice(language,preOrderCommonVo, computedOrderCommonPriceRequest, user);
        List<StoreOrderInfo> orderInfoList = new ArrayList<>();
        List<StoreOrderInfo> orderInfoCardList = new ArrayList<>();
        UserAddress userAddress = null;
        for (CreateCommonOrderRequest.ShopComputedPriceDetail shopItem : shopComputedPriceDetails) {
            // TODO: 2022/11/23 校验商品库存
            StoreOrderInfo orderInfo = verifyStockShop(language,shopItem, user, preOrderCommonVo, null, request.getAddressId());
            UserAddress address = orderInfo.getUserAddress();
            if (address != null) {
                userAddress = new UserAddress();
                BeanUtils.copyProperties(address, userAddress);
                shopOrderVo.setUserAddress(address);
            }
            if (Objects.equals(vcaProductService.getById(orderInfo.getProductId()).getCid(), Constants.CATEGORY_ID_OF_GIFT_CARD_TYPE)) {
                orderInfoCardList.add(orderInfo);
            } else {
                orderInfoList.add(orderInfo);
            }
        }
        BigDecimal shopTotalPrice = BigDecimal.ZERO;
        Integer shopTotalCount = 0;
        Integer cardTotalCount = 0;
        BigDecimal cardTotalPrice = BigDecimal.ZERO;
        for (StoreOrderInfo orderInfo : orderInfoList) {
            shopTotalPrice = shopTotalPrice.add(orderInfo.getPrice().multiply(BigDecimal.valueOf(orderInfo.getPayNum())));
            shopTotalCount += orderInfo.getPayNum();
        }
        for (StoreOrderInfo info : orderInfoCardList) {
            cardTotalPrice = cardTotalPrice.add(info.getPrice().multiply(BigDecimal.valueOf(info.getPayNum())));
            cardTotalCount += info.getPayNum();
        }
        shopOrderVo.setShopTotalCount(shopTotalCount);
        shopOrderVo.setCardTotalCount(cardTotalCount);
        shopOrderVo.setShopTotalPrice(shopTotalPrice);
        shopOrderVo.setCardTotalPrice(cardTotalPrice);
        shopOrderVo.setPriceResponse(computedOrderCommonPriceResponse);
        shopOrderVo.setOrderInfoList(orderInfoList);
        shopOrderVo.setOrderInfoCardList(orderInfoCardList);
        return shopOrderVo;
    }

    /**
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private void handleCreateCommonOrderRequest(CreateCommonOrderRequest request, ComputedOrderCommonPriceRequest computedOrderCommonPriceRequest, String preOrderType) {
        computedOrderCommonPriceRequest.setPreOrderNo(request.getPreOrderNo());
        ComputedOrderCommonPriceRequest.CourseComputedPriceDetail courseComputedPriceDetail = new ComputedOrderCommonPriceRequest.CourseComputedPriceDetail();
        if (request.getCourseComputedPriceDetail() != null) {
            CreateCommonOrderRequest.CourseComputedPriceDetail createOrderPriceDetail = request.getCourseComputedPriceDetail();
            courseComputedPriceDetail.setAppointmentsCount(createOrderPriceDetail.getAppointmentsCount());
            courseComputedPriceDetail.setCardId(createOrderPriceDetail.getCardId());
            courseComputedPriceDetail.setInvoiceRequired(createOrderPriceDetail.getInvoiceRequired());
            List<ComputedOrderCommonPriceRequest.UserInformation> giveAwayToOthersMap = new ArrayList<>();
            for (CreateCommonOrderRequest.UserInformation userInformation : createOrderPriceDetail.getGiveAwayToOthersMap()) {
                ComputedOrderCommonPriceRequest.UserInformation information = new ComputedOrderCommonPriceRequest.UserInformation();
                information.setAppointmentOfClassStaff(userInformation.getAppointmentOfClassStaff());
                information.setAppointmentPhoneNumber(userInformation.getAppointmentPhoneNumber());
                giveAwayToOthersMap.add(information);
            }
            courseComputedPriceDetail.setGiveAwayToOthersMap(giveAwayToOthersMap);
            computedOrderCommonPriceRequest.setCourseComputedPriceDetail(courseComputedPriceDetail);
        }
        if (request.getShopComputedPriceDetails() != null) {
            List<ComputedOrderCommonPriceRequest.ShopComputedPriceDetail> shopComputedPriceDetails = new ArrayList<>();
            request.getShopComputedPriceDetails().forEach(shopComputedPriceDetail -> {
                ComputedOrderCommonPriceRequest.ShopComputedPriceDetail shopDetail = new ComputedOrderCommonPriceRequest.ShopComputedPriceDetail();
//                shopDetail.setPrice(shopComputedPriceDetail.getPrice());
                shopDetail.setCount(shopComputedPriceDetail.getCount());
//                shopDetail.setLabelColor(shopComputedPriceDetail.getLabelColor());
                shopDetail.setAttrValueId(shopComputedPriceDetail.getAttrValueId());
                shopDetail.setProductId(shopComputedPriceDetail.getProductId());
//                shopDetail.setType(shopComputedPriceDetail.getType());
//                shopDetail.setName(shopComputedPriceDetail.getName());
                shopDetail.setShoppingCartId(shopComputedPriceDetail.getShoppingCartId());
                shopComputedPriceDetails.add(shopDetail);
            });
            computedOrderCommonPriceRequest.setShopComputedPriceDetails(shopComputedPriceDetails);
        }
    }

    /**
     * @Description:校验商品库存
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private StoreOrderInfo verifyStockShop(String language,CreateCommonOrderRequest.ShopComputedPriceDetail shopItem, User user, PreOrderCommonVo preOrderCommonVo, String orderNo, Integer addressId) {
        if (preOrderCommonVo.getPreOrderType().equals("shoppingCart")) {
            if (ObjectUtil.isNull(shopItem.getShoppingCartId())) {
                if("en".equals(language)){
                    throw new VcaException("The cart number cannot be empty");
                }else{
                    throw new VcaException("购物车编号不能为空");
                }
            }
            StoreCart cart = cartService.getByIdAndUid(shopItem.getShoppingCartId(), user.getUid());
            if (ObjectUtil.isNull(cart)) {
                if("en".equals(language)){
                    throw new VcaException("No corresponding shopping cart information found");
                }else{
                    throw new VcaException("未找到对应的购物车信息");
                }
            }
        }
        if (ObjectUtil.isNull(shopItem.getProductId())) {
            if("en".equals(language)){
                throw new VcaException("The item ID cannot be empty");
            }else{
                throw new VcaException("商品ID不能为空");
            }
        }
        if (ObjectUtil.isNull(shopItem.getAttrValueId())) {
            if("en".equals(language)){
                throw new VcaException("Item property values cannot be empty");
            }else{
                throw new VcaException("商品属性值不能为空");
            }
        }
        // TODO: 2022/11/23 查询商品信息
        VcaProduct vcaProduct = vcaProductService.getById(shopItem.getProductId());
        if (ObjectUtil.isNull(vcaProduct)) {
            if("en".equals(language)){
                throw new VcaException("Product information does not exist, please refresh and select again");
            }else{
                throw new VcaException("商品信息不存在，请刷新后重新选择");
            }
        }
        if (vcaProduct.getIsDeleted()) {
            if("en".equals(language)){
                throw new VcaException("The product has been deleted, please refresh and select again");
            }else{
                throw new VcaException("商品已删除，请刷新后重新选择");
            }
        }
        if (!vcaProduct.getIsShow()) {
            if("en".equals(language)){
                throw new VcaException("The product has been removed from the shelves, please refresh and select again");
            }else{
                throw new VcaException("商品已下架，请刷新后重新选择");
            }
        }
        if (vcaProduct.getStock() < shopItem.getCount()) {
            if("en".equals(language)){
                throw new VcaException("Product stock is insufficient, please refresh and select again");
            }else{
                throw new VcaException("商品库存不足，请刷新后重新选择");
            }
        }
        VcaProductAttrValue vcaProductAttrValue = vcaProductAttrValueService.getByIdAndProductIdAndType(shopItem.getAttrValueId(), shopItem.getProductId(), Constants.PRODUCT_TYPE_NORMAL);
        if (ObjectUtil.isNull(vcaProductAttrValue)) {
            if("en".equals(language)){
                throw new VcaException("Product specifications do not exist, please refresh and select again");
            }else{
                throw new VcaException("商品规格信息不存在，请刷新后重新选择");
            }
        }
        if (vcaProductAttrValue.getStock() < shopItem.getCount()) {
            if("en".equals(language)){
                throw new VcaException("Product stock is insufficient, please refresh and select again");
            }else{
                throw new VcaException("商品库存不足，请刷新后重新选择");
            }
        }
        PreOrderCommonVo.PreOrderProductDetail preOrderProductDetail = new PreOrderCommonVo.PreOrderProductDetail();
        preOrderProductDetail.setProductId(vcaProduct.getId());


        preOrderProductDetail.setNameEn(vcaProduct.getNameEn());
        preOrderProductDetail.setName(vcaProduct.getName());

        preOrderProductDetail.setIntroduction(vcaProduct.getIntroductionEn());
        preOrderProductDetail.setIntroduction(vcaProduct.getIntroduction());

        preOrderProductDetail.setFaceValue(vcaProduct.getFaceValue());
        preOrderProductDetail.setAttrValueId(vcaProductAttrValue.getId());
        preOrderProductDetail.setImage(StringUtil.isNotBlank(vcaProductAttrValue.getImage()) ? vcaProductAttrValue.getImage() : vcaProduct.getImage());
        preOrderProductDetail.setSkuEn(vcaProductAttrValue.getSukEn());
        preOrderProductDetail.setSku(vcaProductAttrValue.getSuk());
        preOrderProductDetail.setPrice(vcaProductAttrValue.getPrice());
        preOrderProductDetail.setBuyNum(shopItem.getCount());
        preOrderProductDetail.setWeight(vcaProductAttrValue.getWeight());
        preOrderProductDetail.setVolume(vcaProductAttrValue.getVolume());
        preOrderProductDetail.setIsbnCode(vcaProductAttrValue.getIsbnCode());

        preOrderProductDetail.setTypeEn(categoryService.getById(vcaProduct.getCid()).getNameEn());
        preOrderProductDetail.setType(categoryService.getById(vcaProduct.getCid()).getName());

        preOrderProductDetail.setLabelColor(categoryService.getById(vcaProduct.getCid()).getLabelColor());
        preOrderProductDetail.setCardNo(vcaProduct.getCardNo());
        preOrderProductDetail.setUseAround(vcaProduct.getUseAround());
        preOrderProductDetail.setUseType(vcaProduct.getUseType());
        preOrderProductDetail.setPrimaryKey(vcaProduct.getPrimaryKey());
        preOrderProductDetail.setEndTime(vcaProduct.getEndTime());

        StoreOrderInfo orderInfo = new StoreOrderInfo();
        // TODO: 2022/11/11 生成订单号
        String merOrderNo = VcaUtil.getOrderNo("order");
        orderInfo.setOrderNo(orderNo);
        System.out.println(language+"$$$$$$$$$$$$$$");
        System.out.println(preOrderProductDetail+"===============");
        orderInfo.setMerOrderNo(merOrderNo);
        orderInfo.setInfo(JSON.toJSON(preOrderProductDetail).toString());
        orderInfo.setType(Constants.ORDER_TYPE_PRODUCT);
        orderInfo.setProductId(vcaProduct.getId());

        orderInfo.setNameEn(vcaProduct.getNameEn());
        orderInfo.setName(vcaProduct.getName());

        orderInfo.setAttrValueId(vcaProductAttrValue.getId());
        orderInfo.setImage(StringUtils.isNotBlank(vcaProductAttrValue.getImage()) ? vcaProductAttrValue.getImage() : vcaProduct.getCoverImage());

        orderInfo.setSkuEn(vcaProductAttrValue.getSukEn());
        orderInfo.setSku(vcaProductAttrValue.getSuk());

        orderInfo.setPrice(vcaProductAttrValue.getPrice());
        orderInfo.setPayNum(shopItem.getCount());
        orderInfo.setWeight(vcaProductAttrValue.getWeight());
        orderInfo.setVolume(vcaProductAttrValue.getVolume());
        orderInfo.setStatus(0);
        orderInfo.setPayPrice(orderInfo.getPrice().multiply(BigDecimal.valueOf(orderInfo.getPayNum())));
        if (!Objects.equals(vcaProduct.getCid(), Constants.CATEGORY_ID_OF_GIFT_CARD_TYPE)) {
            UserAddress userAddress = userAddressService.getOne(new LambdaQueryWrapper<UserAddress>().eq(UserAddress::getId, addressId).eq(UserAddress::getUid, user.getUid()).eq(UserAddress::getIsDel, false));
            if (userAddress == null) {
                if("en".equals(language)){
                    throw new VcaException("The current user address does not exist");
                }else{
                    throw new VcaException("当前用户地址不存在");
                }
            }
            orderInfo.setUserAddress(userAddress);
            orderInfo.setAddress(userAddress.getProvince() + " " + userAddress.getCity() + "" + userAddress.getDistrict() + "" + userAddress.getDetail());
        }
        orderInfo.setRefundStatus(0);
        return orderInfo;
    }

    /**
     * @Description:处理订单价格
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    private ComputedOrderCommonPriceResponse computedCommonPrice(String language,PreOrderCommonVo preOrderCommonVo, ComputedOrderCommonPriceRequest request, User user) {
        ComputedOrderCommonPriceResponse computedOrderCommonPriceResponse = new ComputedOrderCommonPriceResponse();
        switch (preOrderCommonVo.getPreOrderType()) {
            case "shoppingCart":
                computedOrderCommonPriceResponse = handleTypeShoppingCartComputedPrice(language,preOrderCommonVo, request, user);
                break;
            case "buyNow":
                computedOrderCommonPriceResponse = handleTypeBuyNowComputedPrice(language,preOrderCommonVo, request, user);
                break;
            default:
                break;
        }
        return computedOrderCommonPriceResponse;
    }

    /**
     * @Description:购物车下单处理订单价格
     * @Author: chenBing
     * @Date: 2022/11/23
     */
    private ComputedOrderCommonPriceResponse handleTypeShoppingCartComputedPrice(String language,PreOrderCommonVo preOrderCommonVo, ComputedOrderCommonPriceRequest request, User user) {
        ComputedOrderCommonPriceResponse computedOrderCommonPriceResponse = new ComputedOrderCommonPriceResponse();
        List<ComputedOrderCommonPriceRequest.ShopComputedPriceDetail> shopComputedPriceDetails = request.getShopComputedPriceDetails();
        List<PreOrderCommonRequest.PreOrderDetailRequest> orderDetails = new ArrayList<>();
        for (ComputedOrderCommonPriceRequest.ShopComputedPriceDetail shopComputedPriceDetail : shopComputedPriceDetails) {
            PreOrderCommonRequest.PreOrderDetailRequest preOrderDetailRequest = new PreOrderCommonRequest.PreOrderDetailRequest();
            BeanUtils.copyProperties(shopComputedPriceDetail, preOrderDetailRequest);
            orderDetails.add(preOrderDetailRequest);
        }
        PreOrderCommonVo shopPreOrderCommon = verifyPreOrderShopInformation(language,orderDetails, "no_shopping_car", user);
        computedOrderCommonPriceResponse.setPayTotalFree(shopPreOrderCommon.getTotalPrice());
        computedOrderCommonPriceResponse.setPayFree(shopPreOrderCommon.getTotalPrice());
        computedOrderCommonPriceResponse.setBuyShopCount(shopPreOrderCommon.getCount());
        computedOrderCommonPriceResponse.setProductTotalPrice(shopPreOrderCommon.getTotalPrice());
        computedOrderCommonPriceResponse.setCount(shopPreOrderCommon.getCount());
        return computedOrderCommonPriceResponse;
    }

    /**
     * @Description:立即购买处理订单价格
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    private ComputedOrderCommonPriceResponse handleTypeBuyNowComputedPrice(String language,PreOrderCommonVo preOrderCommonVo, ComputedOrderCommonPriceRequest request, User user) {
        ComputedOrderCommonPriceResponse computedOrderCommonPriceResponse = new ComputedOrderCommonPriceResponse();
        ComputedOrderCommonPriceRequest.CourseComputedPriceDetail courseComputedPriceDetail = request.getCourseComputedPriceDetail();
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = preOrderCommonVo.getEventInfoDetail();
        switch (preOrderCommonVo.getType()) {
            // TODO: 2022/11/22 课程/套课/讲座/展览
            case 0:
            case 1:
            case 2:
            case 3:
                //todo：获取礼品卡金额
                BigDecimal payTotalFree = new BigDecimal(0);
                computedOrderCommonPriceResponse.setBuyCourseCount(courseComputedPriceDetail.getAppointmentsCount());     //预约人数
                computedOrderCommonPriceResponse.setCount(courseComputedPriceDetail.getAppointmentsCount());
                //课程总价
                payTotalFree = courseInfoDetail.getPrice().multiply(BigDecimal.valueOf(courseComputedPriceDetail.getAppointmentsCount()));
                computedOrderCommonPriceResponse.setPayTotalFree(payTotalFree);
                computedOrderCommonPriceResponse.setEventTotalPrice(payTotalFree);
                Integer cardId = courseComputedPriceDetail.getCardId();
                UserCard userCard = new UserCard();
                if (ObjectUtil.isNotNull(cardId)) {
                    if (cardId != 0) {
                        userCard = userCardService.getById(cardId);
                        computedOrderCommonPriceResponse.setCardFaceValue(userCard.getFaceValue());
                        computedOrderCommonPriceResponse.setPayFree(payTotalFree.subtract(userCard.getFaceValue()));
                    }
                } else {
                    computedOrderCommonPriceResponse.setPayFree(payTotalFree);
                }
                if (preOrderCommonVo.getType() == 3) {
                    if (ObjectUtil.isNotNull(request.getShopComputedPriceDetails())) {
                        List<ComputedOrderCommonPriceRequest.ShopComputedPriceDetail> shopComputedPriceDetails = request.getShopComputedPriceDetails();
                        List<PreOrderCommonRequest.PreOrderDetailRequest> orderDetails = new ArrayList<>();
                        for (ComputedOrderCommonPriceRequest.ShopComputedPriceDetail shopComputedPriceDetail : shopComputedPriceDetails) {
                            PreOrderCommonRequest.PreOrderDetailRequest preOrderDetailRequest = new PreOrderCommonRequest.PreOrderDetailRequest();
                            BeanUtils.copyProperties(shopComputedPriceDetail, preOrderDetailRequest);
                            orderDetails.add(preOrderDetailRequest);
                        }
                        PreOrderCommonVo shopPreOrderCommon = verifyPreOrderShopInformation(language,orderDetails, "no_shopping_car", user);
                        computedOrderCommonPriceResponse.setPayTotalFree(computedOrderCommonPriceResponse.getPayTotalFree().add(shopPreOrderCommon.getTotalPrice()));
                        computedOrderCommonPriceResponse.setPayFree(computedOrderCommonPriceResponse.getPayFree().add(shopPreOrderCommon.getTotalPrice()));
                        computedOrderCommonPriceResponse.setBuyShopCount(shopPreOrderCommon.getCount());
                        computedOrderCommonPriceResponse.setProductTotalPrice(shopPreOrderCommon.getTotalPrice());
                    }
                }
                break;
            // TODO: 2022/11/22 商品  校验商品预下单信息
            case 4:
                List<ComputedOrderCommonPriceRequest.ShopComputedPriceDetail> shopComputedPriceDetails = request.getShopComputedPriceDetails();
                List<PreOrderCommonRequest.PreOrderDetailRequest> orderDetails = new ArrayList<>();
                for (ComputedOrderCommonPriceRequest.ShopComputedPriceDetail shopComputedPriceDetail : shopComputedPriceDetails) {
                    PreOrderCommonRequest.PreOrderDetailRequest preOrderDetailRequest = new PreOrderCommonRequest.PreOrderDetailRequest();
                    BeanUtils.copyProperties(shopComputedPriceDetail, preOrderDetailRequest);
                    orderDetails.add(preOrderDetailRequest);
                }
                PreOrderCommonVo shopPreOrderCommon = verifyPreOrderShopInformation(language,orderDetails, "no_shopping_car", user);
                computedOrderCommonPriceResponse.setPayTotalFree(shopPreOrderCommon.getTotalPrice());
                computedOrderCommonPriceResponse.setPayFree(shopPreOrderCommon.getTotalPrice());
                computedOrderCommonPriceResponse.setProductTotalPrice(shopPreOrderCommon.getTotalPrice());
                computedOrderCommonPriceResponse.setBuyShopCount(shopPreOrderCommon.getCount());
                computedOrderCommonPriceResponse.setCount(shopPreOrderCommon.getCount());
                break;
            default:
                break;
        }
        return computedOrderCommonPriceResponse;
    }


    /**
     * @Description:处理购物车预下单 由于购物车只能添加商品，所以不存在课程/讲座/套课/展览类型的订单
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    private MyRecord handleTypeShoppingCart(String language,PreOrderCommonRequest request, User user) {
        List<PreOrderCommonRequest.PreOrderDetailRequest> orderDetails = request.getOrderDetails();
        MyRecord myRecord = new MyRecord();
        PreOrderCommonVo preOrderCommonVo = verifyPreOrderShopInformation(language,orderDetails, "shoppingCart", user);
        List<Long> cartIdList = request.getOrderDetails().stream().map(PreOrderCommonRequest.PreOrderDetailRequest::getShoppingCartId).distinct().collect(Collectors.toList());
        preOrderCommonVo.setCartIdList(cartIdList);
        //缓存订单
        String key = user.getUid() + DateUtil.getNowTime().toString() + VcaUtil.getUuid();
        redisUtil.set("user_course_order:" + key, JSONObject.toJSONString(preOrderCommonVo));
        myRecord.set("preOrderNo", key);
        return myRecord;
    }

    /**
     * 列表（PC）
     *
     * @param request          请求参数
     * @param pageParamRequest 分页类参数
     * @return CommonPage<StoreOrderDetailResponse>
     */
    @Override
    public CommonPage<StoreOrderDetailResponse> getAdminList(StoreOrderSearchRequest request, PageParamRequest pageParamRequest) {
        Page<Object> startPage = PageHelper.startPage(pageParamRequest.getPage(), pageParamRequest.getLimit());
        QueryWrapper<StoreOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "order_id", "uid", "real_name", "pay_price", "pay_type", "create_time", "status", "refund_status", "refund_reason_wap_img", "refund_reason_wap_explain", "refund_reason_wap", "refund_reason", "refund_reason_time", "is_del", "combination_id", "pink_id", "seckill_id", "bargain_id", "verify_code", "remark", "paid", "is_system_del", "shipping_type", "type", "is_alter_price");
        if (StrUtil.isNotBlank(request.getOrderNo())) {
            queryWrapper.eq("order_id", request.getOrderNo());
        }
        getRequestTimeWhere(queryWrapper, request);
        getStatusWhereNew(queryWrapper, request.getStatus());
        if (!request.getType().equals(2)) {
            queryWrapper.eq("type", request.getType());
        }
        queryWrapper.orderByDesc("id");
        List<StoreOrder> orderList = dao.selectList(queryWrapper);
        List<StoreOrderDetailResponse> detailResponseList = new ArrayList<>();
        if (CollUtil.isNotEmpty(orderList)) {
            detailResponseList = formatOrder1(orderList);
        }
        return CommonPage.restPage(CommonPage.copyPageInfo(startPage, detailResponseList));
    }

    /**
     * @Description:根据不同的订单类型处理订单
     * @Author: chenBing
     * @Date: 2022/11/21
     */
    public MyRecord handleTypeBuyNow(String language,PreOrderCommonRequest request, User user) {
        PreOrderCommonVo preOrderCommonVo = new PreOrderCommonVo();
        PreOrderCommonRequest.PreOrderDetailRequestVo preOrderDetail = request.getPreOrderDetail();
        MyRecord myRecord = new MyRecord();
        switch (request.getType()) {
            // TODO: 2022/11/21 课程
            case 0:
                //查询当前课程
                Course course = courseService.getById(preOrderDetail.getMainId());
                // TODO: 2022/11/9 校验预下单课程信息
                preOrderCommonVo = verifyPreOrderCourseInformation(language,course, preOrderDetail);
                break;
            // TODO: 2022/11/21 套课
            case 1:
                //查询当前套课
                CoursePackage coursePackage = coursePackageService.getById(preOrderDetail.getMainId());
                // TODO: 2022/11/21 校验预下单套课信息
                preOrderCommonVo = verifyPreOrderCoursePackageInformation(language,coursePackage, preOrderDetail);
                break;
            // TODO: 2022/11/21 讲座
            case 2:
                Talk talk = talkService.getById(preOrderDetail.getMainId());
                // TODO: 2022/11/22 校验预下单讲座信息
                preOrderCommonVo = verifyPreOrderTalkInformation(language,talk, preOrderDetail);
                break;
            // TODO: 2022/11/21 展览
            case 3:
                Exhibition exhibition = exhibitionService.getById(preOrderDetail.getMainId());
                // TODO: 2022/11/22 校验预下单展览信息
                preOrderCommonVo = verifyPreOrderExhibitionInformation(language,exhibition, request);
                break;
            // TODO: 2022/11/21 商品  校验商品预下单信息
            case 4:
                List<PreOrderCommonRequest.PreOrderDetailRequest> orderDetails = request.getOrderDetails();
                preOrderCommonVo = verifyPreOrderShopInformation(language,orderDetails, "no_shopping_car", user);
                break;
            default:
                break;
        }
        //缓存订单
        String key = user.getUid() + DateUtil.getNowTime().toString() + VcaUtil.getUuid();
        redisUtil.set("user_course_order:" + key, JSONObject.toJSONString(preOrderCommonVo));
        myRecord.set("preOrderNo", key);
        return myRecord;
    }

    /**
     * @Description:校验商品预下单信息
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    private PreOrderCommonVo verifyPreOrderShopInformation(String language,List<PreOrderCommonRequest.PreOrderDetailRequest> orderDetails, String type, User user) {
        PreOrderCommonVo preOrderCommonVo = new PreOrderCommonVo();
        List<PreOrderCommonVo.PreOrderProductDetail> preOrderProductDetails = new ArrayList<>();
        int count = 0;
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (PreOrderCommonRequest.PreOrderDetailRequest orderDetail : orderDetails) {
            PreOrderCommonVo.PreOrderProductDetail preOrderProductDetail = new PreOrderCommonVo.PreOrderProductDetail();
            if (type.equals("shoppingCart")) {
                // TODO: 2022/11/22 购物车预下单校验
                if (ObjectUtil.isNull(orderDetail.getShoppingCartId())) {
                    if("en".equals(language)){
                        throw new VcaException("The cart number cannot be empty");
                    }else{
                        throw new VcaException("购物车编号不能为空");
                    }
                }
                StoreCart cart = cartService.getByIdAndUid(orderDetail.getShoppingCartId(), user.getUid());
                if (ObjectUtil.isNull(cart)) {
                    if("en".equals(language)){
                        throw new VcaException("No corresponding shopping cart information found");
                    }else{
                        throw new VcaException("未找到对应的购物车信息");
                    }
                }
            }
            if (ObjectUtil.isNull(orderDetail.getProductId())) {
                if("en".equals(language)){
                    throw new VcaException("The item ID cannot be empty");
                }else{
                    throw new VcaException("商品ID不能为空");
                }
            }
            if (ObjectUtil.isNull(orderDetail.getAttrValueId())) {
                if("en".equals(language)){
                    throw new VcaException("Item property values cannot be empty");
                }else{
                    throw new VcaException("商品属性值不能为空");
                }
            }
            // TODO: 2022/11/22 查询商品信息
            VcaProduct vcaProduct = vcaProductService.getById(orderDetail.getProductId());
            if (ObjectUtil.isNull(vcaProduct)) {
                if("en".equals(language)){
                    throw new VcaException("Product information does not exist, please refresh and select again");
                }else{
                    throw new VcaException("商品信息不存在，请刷新后重新选择");
                }
            }
            if (vcaProduct.getIsDeleted()) {
                if("en".equals(language)){
                    throw new VcaException("The product has been deleted, please refresh and select again");
                }else{
                    throw new VcaException("商品已删除，请刷新后重新选择");
                }
            }
            if (!vcaProduct.getIsShow()) {
                if("en".equals(language)){
                    throw new VcaException("The product has been removed from the shelves, please refresh and select again");
                }else{
                    throw new VcaException("商品已下架，请刷新后重新选择");
                }
            }
            if (vcaProduct.getStock() < orderDetail.getCount()) {
                if("en".equals(language)){
                    throw new VcaException("Product stock is insufficient, please refresh and select again");
                }else{
                    throw new VcaException("商品库存不足，请刷新后重新选择");
                }
            }
            // TODO: 2022/11/22 查询商品规格属性值信息
            VcaProductAttrValue vcaProductAttrValue = vcaProductAttrValueService.getByIdAndProductIdAndType(orderDetail.getAttrValueId(), orderDetail.getProductId(), Constants.PRODUCT_TYPE_NORMAL);
            if (ObjectUtil.isNull(vcaProductAttrValue)) {
                if("en".equals(language)){
                    throw new VcaException("Product specifications do not exist, please refresh and select again");
                }else{
                    throw new VcaException("商品规格信息不存在，请刷新后重新选择");
                }
            }
            if (vcaProductAttrValue.getStock() < orderDetail.getCount()) {
                if("en".equals(language)){
                    throw new VcaException("Product stock is insufficient, please refresh and select again");
                }else{
                    throw new VcaException("商品库存不足，请刷新后重新选择");
                }
            }
            preOrderProductDetail.setProductId(vcaProduct.getId());

            preOrderProductDetail.setNameEn(vcaProduct.getNameEn());
            preOrderProductDetail.setName(vcaProduct.getName());

            preOrderProductDetail.setIntroductionEn(vcaProduct.getIntroductionEn());
            preOrderProductDetail.setIntroduction(vcaProduct.getIntroduction());

            preOrderProductDetail.setTypeEn(categoryService.getById(vcaProduct.getCid()).getNameEn());
            preOrderProductDetail.setType(categoryService.getById(vcaProduct.getCid()).getName());

            preOrderProductDetail.setFaceValue(vcaProduct.getFaceValue());
            preOrderProductDetail.setAttrValueId(vcaProductAttrValue.getId());
            preOrderProductDetail.setImage(StringUtil.isNotBlank(vcaProductAttrValue.getImage()) ? vcaProductAttrValue.getImage() : vcaProduct.getImage());

            preOrderProductDetail.setSkuEn(vcaProductAttrValue.getSukEn());
            preOrderProductDetail.setSku(vcaProductAttrValue.getSuk());

            preOrderProductDetail.setPrice(vcaProductAttrValue.getPrice());
            preOrderProductDetail.setBuyNum(orderDetail.getCount());
            preOrderProductDetail.setWeight(vcaProductAttrValue.getWeight());
            preOrderProductDetail.setVolume(vcaProductAttrValue.getVolume());
            preOrderProductDetail.setIsbnCode(vcaProductAttrValue.getIsbnCode());
            preOrderProductDetail.setLabelColor(categoryService.getById(vcaProduct.getCid()).getLabelColor());
            preOrderProductDetail.setCardNo(vcaProduct.getCardNo());
            preOrderProductDetail.setUseAround(vcaProduct.getUseAround());
            preOrderProductDetail.setUseType(vcaProduct.getUseType());
            preOrderProductDetail.setPrimaryKey(vcaProduct.getPrimaryKey());
            preOrderProductDetail.setEndTime(vcaProduct.getEndTime());
            count += orderDetail.getCount();
            BigDecimal toPrice = preOrderProductDetail.getPrice().multiply(BigDecimal.valueOf(preOrderProductDetail.getBuyNum()));
            totalPrice = totalPrice.add(toPrice);
            preOrderProductDetails.add(preOrderProductDetail);
        }
        preOrderCommonVo.setCount(count);
        preOrderCommonVo.setTotalPrice(totalPrice);
        preOrderCommonVo.setTotalPriceShop(totalPrice);
        preOrderCommonVo.setProductDetail(preOrderProductDetails);
        preOrderCommonVo.setType(4);
        if (type.equals("shoppingCart")) {
            preOrderCommonVo.setPreOrderType("shoppingCart");
        } else {
            preOrderCommonVo.setPreOrderType("buyNow");
        }
        return preOrderCommonVo;
    }

    /**
     * @Description:校验预下单展览信息
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    private PreOrderCommonVo verifyPreOrderExhibitionInformation(String language,Exhibition exhibition, PreOrderCommonRequest request) {
        PreOrderCommonVo preOrderCommonVo = new PreOrderCommonVo();
        // TODO: 2022/11/22 校验展览信息
        PreOrderCommonRequest.PreOrderDetailRequestVo preOrderDetail = request.getPreOrderDetail();
        if (exhibition == null) {
            if("en".equals(language)){
                throw new VcaException("No exhibition information found");
            }else{
                throw new VcaException("未查询到展览信息");
            }
        }
        PreOrderCommonRequest.PreOrderDetailRequestVo.ScheduleLing scheduleLingVo = preOrderDetail.getScheduleLings().get(0);
        ExhibitionScheduling exhibitionScheduling = exhibitionSchedulingService.getById(scheduleLingVo.getScheduleId());
        if (exhibitionScheduling == null) {
            if("en".equals(language)){
                throw new VcaException("The current exhibition schedule is not found");
            }else{
                throw new VcaException("未查询到当前展览排期");
            }
        }
        if (exhibitionScheduling.getStatus() == 0) {
            if("en".equals(language)){
                throw new VcaException("The scheduled exhibition is not open for booking");
            }else{
                throw new VcaException("该排期展览未开启预约");
            }
        }
        //TODO：获取课程提前停止预约时间
        Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.EXHIBITION_END_ORDER_TIME));
        Date schedulingDate = DateUtil.strToDate(exhibitionScheduling.getSchedulingDate() + " " + exhibitionScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
        DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
        long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
        if (between >= 0) {
            if("en".equals(language)){
                throw new VcaException("Reservations for the exhibition have been closed");
            }else{
                throw new VcaException("展览已停止预约");
            }
        }
        // TODO: 2022/11/10 处理课程详情
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = new PreOrderCommonVo.CourseInfoDetail();

        courseInfoDetail.setNameEn(exhibition.getNameEn());
        courseInfoDetail.setName(exhibition.getName());

        courseInfoDetail.setPrice(exhibitionScheduling.getPrice());
        courseInfoDetail.setMainId(preOrderDetail.getMainId());
        List<PreOrderCommonVo.CourseInfoDetail.Scheduling> schedulings = new ArrayList<>();
        PreOrderCommonVo.CourseInfoDetail.Scheduling scheduling = new PreOrderCommonVo.CourseInfoDetail.Scheduling();
        scheduling.setScheduleId(scheduleLingVo.getScheduleId());
        scheduling.setCourseId(scheduleLingVo.getCourseId());

        scheduling.setCourseNameEn(exhibition.getNameEn());
        scheduling.setCourseName(exhibition.getName());

        scheduling.setSchedulingDate(exhibitionScheduling.getSchedulingDate());
        scheduling.setSchedulingEndTime(exhibitionScheduling.getSchedulingEndTime());
        scheduling.setSchedulingStartTime(exhibitionScheduling.getSchedulingStartTime());

        scheduling.setCourseAddressEn(getAddressInfoMap("en",exhibition.getCourseAddressId()));
        scheduling.setCourseAddress(getAddressInfoMap("cn",exhibition.getCourseAddressId()));

        scheduling.setCoverImage(exhibition.getCover());
        schedulings.add(scheduling);
        courseInfoDetail.setSchedulings(schedulings);

        courseInfoDetail.setTypeNameEn("Exhibition");
        courseInfoDetail.setTypeName("展览");

        //courseInfoDetail.setTypeNameEn(exhibition.getCityNameEn());
        //courseInfoDetail.setTypeName(exhibition.getCityName());

        courseInfoDetail.setTypeLabelColor("#B4B19E");
        courseInfoDetail.setCoverImage(exhibition.getCover());
        preOrderCommonVo.setEventInfoDetail(courseInfoDetail);
        preOrderCommonVo.setType(Constants.ORDER_TYPE_EXHIBITION);
        preOrderCommonVo.setPreOrderType("buyNow");
        preOrderCommonVo.setTotalPriceCourse(courseInfoDetail.getPrice().multiply(BigDecimal.valueOf(preOrderDetail.getCount())));
        // TODO: 2022/11/22 附加商品校验
        PreOrderCommonVo shopPreOrder = new PreOrderCommonVo();
        if (request.getOrderDetails() != null) {
            shopPreOrder = verifyPreOrderShopInformation(language,request.getOrderDetails(), "no_shopping_car", null);
            preOrderCommonVo.setTotalPriceShop(shopPreOrder.getTotalPrice());
            preOrderCommonVo.setProductDetail(shopPreOrder.getProductDetail());
        }
        preOrderCommonVo.setTotalPrice(preOrderCommonVo.getTotalPriceCourse().add(preOrderCommonVo.getTotalPriceShop()));
        return preOrderCommonVo;
    }

    /**
     * @Description:检验预下单讲座信息
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    private PreOrderCommonVo verifyPreOrderTalkInformation(String language,Talk talk, PreOrderCommonRequest.PreOrderDetailRequestVo request) {
        PreOrderCommonVo preOrderCommonVo = new PreOrderCommonVo();
        if (talk == null) {
            if("en".equals(language)){
                throw new VcaException("The current lecture information is not found");
            }else{
                throw new VcaException("未查询到当前讲座信息");
            }

        }
        PreOrderCommonRequest.PreOrderDetailRequestVo.ScheduleLing scheduleLingVo = request.getScheduleLings().get(0);
        TalkScheduling talkScheduling = talkSchedulingService.getById(scheduleLingVo.getScheduleId());
        if (talkScheduling == null) {
            if("en".equals(language)){
                throw new VcaException("The current lecture schedule is not found");
            }else{
                throw new VcaException("未查询到当前讲座排期");
            }
        }
        if (talkScheduling.getStatus() == 0) {
            if("en".equals(language)){
                throw new VcaException("The scheduled lecture is not open for booking");
            }else{
                throw new VcaException("该排期讲座未开启预约");
            }
        }
        if (talkScheduling.getQuota() <= 0) {
            if("en".equals(language)){
                throw new VcaException("The lecture is currently full");
            }else{
                throw new VcaException("当前讲座已满");
            }
        }
        //TODO：获取课程提前停止预约时间
        Integer courseEndOrderTimeHour = 0;
        if (talk.getTalkType() == 1) {
            courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.TALK_END_ORDER_TIME));
            Date schedulingDate = DateUtil.strToDate(talkScheduling.getSchedulingDate() + " " + talkScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
            DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
            long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
            if (between >= 0) {
                if("en".equals(language)){
                    throw new VcaException("Lectures are no longer reserved");
                }else{
                    throw new VcaException("讲座已停止预约");
                }
            }
        }
        if (talk.getTalkType() == 2) {
            courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.ONLINE_TALK_END_ORDER_TIME));
        }
        // TODO: 2022/11/10 处理课程详情
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = new PreOrderCommonVo.CourseInfoDetail();

        courseInfoDetail.setNameEn(talk.getNameEn());
        courseInfoDetail.setName(talk.getName());

        courseInfoDetail.setPrice(talkScheduling.getPrice());
        courseInfoDetail.setMainId(request.getMainId());
        List<PreOrderCommonVo.CourseInfoDetail.Scheduling> schedulings = new ArrayList<>();
        PreOrderCommonVo.CourseInfoDetail.Scheduling scheduling = new PreOrderCommonVo.CourseInfoDetail.Scheduling();
        scheduling.setScheduleId(scheduleLingVo.getScheduleId());
        scheduling.setCourseId(scheduleLingVo.getCourseId());

        scheduling.setCourseNameEn(talk.getNameEn());
        scheduling.setCourseName(talk.getName());

        scheduling.setSchedulingDate(talkScheduling.getSchedulingDate());
        scheduling.setSchedulingEndTime(talkScheduling.getSchedulingEndTime());
        scheduling.setSchedulingStartTime(talkScheduling.getSchedulingStartTime());

        scheduling.setLanguageEn(getLanguage("en",talkScheduling.getCourseLanguageId()));
        scheduling.setLanguage(getLanguage("cn",talkScheduling.getCourseLanguageId()));

        if (talk.getTalkType() == 1) {
            scheduling.setCourseAddressEn(getAddressInfoMap("en",talk.getAddressId()));
            scheduling.setCourseAddress(getAddressInfoMap("cn",talk.getAddressId()));

            scheduling.setLiveBroadLink(ObjectUtil.isNull(talkScheduling.getLiveId()) ? null : systemConfigService.getValueByKey(Constants.VHALL_LINK) + talkScheduling.getLiveId());
            scheduling.setViewingPlatformName(talk.getViewingPlatformName());
        }
        courseInfoDetail.setTalkType(talk.getTalkType());
        scheduling.setCoverImage(talk.getCoverImage());
        schedulings.add(scheduling);
        courseInfoDetail.setSchedulings(schedulings);

        courseInfoDetail.setTypeNameEn(talk.getTalkType() == 1 ? "In-person Talk" : "Online Talk");
        courseInfoDetail.setTypeName(talk.getTalkType() == 1 ? "线下讲座" : "线上讲座");

        courseInfoDetail.setTypeLabelColor("#B4B19E");
        courseInfoDetail.setCoverImage(talk.getCoverImage());
        preOrderCommonVo.setEventInfoDetail(courseInfoDetail);
        preOrderCommonVo.setType(Constants.ORDER_TYPE_TALK);
        preOrderCommonVo.setPreOrderType("buyNow");
        preOrderCommonVo.setTotalPrice(courseInfoDetail.getPrice().multiply(BigDecimal.valueOf(request.getCount())));
        preOrderCommonVo.setTotalPriceCourse(courseInfoDetail.getPrice().multiply(BigDecimal.valueOf(request.getCount())));
        return preOrderCommonVo;
    }

    /**
     * @Description:校验预下单套课信息
     * @Author: chenBing
     * @Date: 2022/11/22
     */
    private PreOrderCommonVo verifyPreOrderCoursePackageInformation(String language,CoursePackage coursePackage, PreOrderCommonRequest.PreOrderDetailRequestVo requestVo) {
        PreOrderCommonVo preOrderCommonVo = new PreOrderCommonVo();
        if (coursePackage == null) {
            if("en".equals(language)){
                throw new VcaException("The current suite is not found");
            }else{
                throw new VcaException("未查询到当前套课");
            }
        }
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = new PreOrderCommonVo.CourseInfoDetail();
        List<PreOrderCommonRequest.PreOrderDetailRequestVo.ScheduleLing> taoKeSchedules = requestVo.getScheduleLings();
        List<PreOrderCommonVo.CourseInfoDetail.Scheduling> schedulings = new ArrayList<>();
        for (PreOrderCommonRequest.PreOrderDetailRequestVo.ScheduleLing scheduleLingVo : taoKeSchedules) {
            CourseScheduling courseScheduling = courseSchedulingService.getById(scheduleLingVo.getScheduleId());
            if (courseScheduling == null) {
                if("en".equals(language)){
                    throw new VcaException("The current course schedule is not found");
                }else{
                    throw new VcaException("未查询到当前课程排期");
                }
            }
            if (!courseScheduling.getStatus()) {
                if("en".equals(language)){
                    throw new VcaException("This scheduled course is not open for booking");
                }else{
                    throw new VcaException("该排期课程未开启预约");
                }
            }
            if (courseScheduling.getExternalLimit() <= 0) {
                if("en".equals(language)){
                    throw new VcaException("The current seat is full");
                }else{
                    throw new VcaException("当前席位已满");
                }
            }
            //TODO：获取课程提前停止预约时间
            Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.COURSE_END_ORDER_TIME));
            Date schedulingDate = DateUtil.strToDate(courseScheduling.getSchedulingDate() + " " + courseScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
            DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
            long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
            if (between >= 0) {
                if("en".equals(language)){
                    throw new VcaException("Classes are no longer reserved");
                }else{
                    throw new VcaException("课程已停止预约");
                }
            }
            PreOrderCommonVo.CourseInfoDetail.Scheduling scheduling = new PreOrderCommonVo.CourseInfoDetail.Scheduling();
            Course course = courseService.getById(courseScheduling.getCourseId());
            scheduling.setScheduleId(scheduleLingVo.getScheduleId());
            scheduling.setCourseId(scheduleLingVo.getCourseId());

            scheduling.setCourseNameEn(course.getNameEn());
            scheduling.setCourseName(course.getName());

            scheduling.setCoverImage(course.getCover());
            scheduling.setSchedulingDate(courseScheduling.getSchedulingDate());
            scheduling.setSchedulingEndTime(courseScheduling.getSchedulingEndTime());
            scheduling.setSchedulingStartTime(courseScheduling.getSchedulingStartTime());

            scheduling.setLanguageEn(getLanguage("en",courseScheduling.getCourseLanguageId()));
            scheduling.setLanguage(getLanguage("cn",courseScheduling.getCourseLanguageId()));

            if (course == null) {
                if("en".equals(language)){
                    throw new VcaException("The current suite contains courses that do not exist");
                }else{
                    throw new VcaException("当前套课中包含不存在的课程");
                }
            }
            scheduling.setCourseAddress(getAddressInfoMap(language,course.getCourseAddressId()));
            schedulings.add(scheduling);
        }

        courseInfoDetail.setNameEn(coursePackage.getNameEn());
        courseInfoDetail.setName(coursePackage.getName());

        courseInfoDetail.setPrice(getPrice(coursePackage.getCoursePackagePriceId()));
        courseInfoDetail.setMainId(requestVo.getMainId());
        courseInfoDetail.setSchedulings(schedulings);
        Category category = categoryService.getById(coursePackage.getCourseTypeId());

        courseInfoDetail.setTypeNameEn(category.getNameEn());
        courseInfoDetail.setTypeName(category.getName());

        courseInfoDetail.setTypeLabelColor(category.getLabelColor());
        courseInfoDetail.setCoverImage(coursePackage.getCoverImage());
        preOrderCommonVo.setEventInfoDetail(courseInfoDetail);
        preOrderCommonVo.setType(Constants.ORDER_TYPE_PACKAGE);
        preOrderCommonVo.setPreOrderType("buyNow");
        preOrderCommonVo.setTotalPrice(courseInfoDetail.getPrice().multiply(BigDecimal.valueOf(requestVo.getCount())));
        preOrderCommonVo.setTotalPriceCourse(courseInfoDetail.getPrice().multiply(BigDecimal.valueOf(requestVo.getCount())));
        return preOrderCommonVo;
    }

    /**
     * @Description:校验预下单课程信息
     * @Author: chenBing
     * @Date: 2022/11/9
     */
    private PreOrderCommonVo verifyPreOrderCourseInformation(String language,Course course, PreOrderCommonRequest.PreOrderDetailRequestVo request) {
        PreOrderCommonVo preOrderCourseVo = new PreOrderCommonVo();
        if (course == null) {
            if("en".equals(language)){
                throw new VcaException("The current course is not found");
            }else{
                throw new VcaException("未查询到当前课程");
            }

        }
        PreOrderCommonRequest.PreOrderDetailRequestVo.ScheduleLing scheduleLingVo = request.getScheduleLings().get(0);
        CourseScheduling courseScheduling = courseSchedulingService.getById(scheduleLingVo.getScheduleId());
        if (courseScheduling == null) {
            if("en".equals(language)){
                throw new VcaException("未查询到当前课程排期");
            }else{
                throw new VcaException("未查询到当前课程排期");
            }
        }
        if (!courseScheduling.getStatus()) {
            if("en".equals(language)){
                throw new VcaException("The current course schedule is not found");
            }else{
                throw new VcaException("该排期课程未开启预约");
            }
        }
        if (courseScheduling.getExternalLimit() <= 0) {
            if("en".equals(language)){
                throw new VcaException("The current seat is full");
            }else{
                throw new VcaException("当前席位已满");
            }

        }
        //TODO：获取课程提前停止预约时间
        Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.COURSE_END_ORDER_TIME));
        Date schedulingDate = DateUtil.strToDate(courseScheduling.getSchedulingDate() + " " + courseScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
        DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
        long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
        if (between >= 0) {
            if("en".equals(language)){
                throw new VcaException("Classes are no longer reserved");
            }else{
                throw new VcaException("课程已停止预约");
            }

        }
        // TODO: 2022/11/10 处理课程详情
        PreOrderCommonVo.CourseInfoDetail courseInfoDetail = new PreOrderCommonVo.CourseInfoDetail();

        courseInfoDetail.setName(course.getName());
        courseInfoDetail.setNameEn(course.getNameEn());

        courseInfoDetail.setMainId(request.getMainId());
        List<PreOrderCommonVo.CourseInfoDetail.Scheduling> schedulings = new ArrayList<>();
        PreOrderCommonVo.CourseInfoDetail.Scheduling scheduling = new PreOrderCommonVo.CourseInfoDetail.Scheduling();
        scheduling.setScheduleId(scheduleLingVo.getScheduleId());
        scheduling.setCourseId(scheduleLingVo.getCourseId());

        scheduling.setCourseNameEn(course.getNameEn());
        scheduling.setCourseName(course.getName());

        scheduling.setSchedulingDate(courseScheduling.getSchedulingDate());
        scheduling.setSchedulingEndTime(courseScheduling.getSchedulingEndTime());
        scheduling.setSchedulingStartTime(courseScheduling.getSchedulingStartTime());

        scheduling.setLanguageEn(getLanguage("en",courseScheduling.getCourseLanguageId()));
        scheduling.setLanguage(getLanguage("cn",courseScheduling.getCourseLanguageId()));

        scheduling.setCourseAddressEn(getAddressInfoMap("en",course.getCourseAddressId()));
        scheduling.setCourseAddress(getAddressInfoMap("cn",course.getCourseAddressId()));

        scheduling.setCoverImage(course.getCover());
        schedulings.add(scheduling);
        courseInfoDetail.setSchedulings(schedulings);
        Category category = categoryService.getById(course.getCourseTypeId());

        courseInfoDetail.setTypeNameEn(category.getNameEn());
        courseInfoDetail.setTypeName(category.getName());

        courseInfoDetail.setTypeLabelColor(category.getLabelColor());
        courseInfoDetail.setPrice(getPrice(courseScheduling.getPriceId()));
        courseInfoDetail.setCoverImage(course.getCover());
        preOrderCourseVo.setEventInfoDetail(courseInfoDetail);
        preOrderCourseVo.setType(Constants.ORDER_TYPE_COURSE);
        preOrderCourseVo.setPreOrderType("buyNow");
        preOrderCourseVo.setTotalPrice(courseInfoDetail.getPrice().multiply(BigDecimal.valueOf(request.getCount())));
        preOrderCourseVo.setTotalPriceCourse(courseInfoDetail.getPrice().multiply(BigDecimal.valueOf(request.getCount())));
        return preOrderCourseVo;
    }

    /**
     * 获取request的where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param request      StoreOrderSearchRequest 请求参数
     */
    private void getRequestTimeWhere(QueryWrapper<StoreOrder> queryWrapper, StoreOrderSearchRequest request) {
        if (StringUtils.isNotBlank(request.getDateLimit())) {
            dateLimitUtilVo dateLimitUtilVo = DateUtil.getDateLimit(request.getDateLimit());
            queryWrapper.between("create_time", dateLimitUtilVo.getStartTime(), dateLimitUtilVo.getEndTime());
        }
    }

    /**
     * 根据订单状态获取where条件
     *
     * @param queryWrapper QueryWrapper<StoreOrder> 表达式
     * @param status       String 类型
     */
    private void getStatusWhereNew(QueryWrapper<StoreOrder> queryWrapper, String status) {
        if (StrUtil.isBlank(status)) {
            return;
        }
        switch (status) {
            case Constants.ORDER_STATUS_ALL: //全部
                break;
            case Constants.ORDER_STATUS_UNPAID: //未支付
                queryWrapper.eq("paid", 0);//支付状态
                queryWrapper.eq("status", 0); //订单状态
                queryWrapper.eq("is_del", 0);//删除状态
                break;
            case Constants.ORDER_STATUS_NOT_SHIPPED: //未发货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 0);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("shipping_type", 1);//配送方式
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_SPIKE: //待收货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 1);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_BARGAIN: //待评价
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 2);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_COMPLETE: //交易完成
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 3);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("is_del", 0);
                break;

            case Constants.ORDER_STATUS_APPLY_REFUNDING: //申请退款
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 1);
                queryWrapper.eq("is_del", 0);
                break;

            case Constants.PENDING_RETURN: //待退货
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 4);
                queryWrapper.eq("is_del", 0);
                break;

            case Constants.IN_RETURN: //退货中
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 5);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_TOBE_WRITTEN_OFF: //待核销
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("status", 0);
                queryWrapper.eq("refund_status", 0);
                queryWrapper.eq("shipping_type", 2);//配送方式
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_REFUNDING: //退款中
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 3);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_REFUNDED: //已退款
                queryWrapper.eq("paid", 1);
                queryWrapper.eq("refund_status", 2);
                queryWrapper.eq("is_del", 0);
                break;
            case Constants.ORDER_STATUS_DELETED: //已删除
                queryWrapper.eq("is_del", 1);
                break;
            default:
                queryWrapper.eq("paid", 1);
                queryWrapper.ne("refund_status", 2);
                break;
        }
        queryWrapper.eq("is_system_del", 0);
    }

    /**
     * 格式化订单信息，对外输出一致
     *
     * @param orderList List<StoreOrder> 订单列表
     * @return List<StoreOrderItemResponse>
     */
    private List<StoreOrderDetailResponse> formatOrder1(List<StoreOrder> orderList) {
        List<StoreOrderDetailResponse> detailResponseList = new ArrayList<>();
        if (CollUtil.isEmpty(orderList)) {
            return detailResponseList;
        }

        //订单id集合
        List<String> orderIdList = orderList.stream().map(StoreOrder::getOrderId).distinct().collect(Collectors.toList());

        //获取订单详情map
        HashMap<String, List<StoreOrderInfoOldVo>> orderInfoList = storeOrderInfoService.getMapInId(orderIdList);
//
//        //根据用户获取信息
//        List<Integer> userIdList = orderList.stream().map(StoreOrder::getUid).distinct().collect(Collectors.toList());
//        //订单用户信息
//        HashMap<Integer, User> userList = userService.getMapListInUid(userIdList);

        for (StoreOrder storeOrder : orderList) {
            StoreOrderDetailResponse storeOrderItemResponse = new StoreOrderDetailResponse();
            BeanUtils.copyProperties(storeOrder, storeOrderItemResponse);

            storeOrderItemResponse.setProductList(orderInfoList.get(storeOrder.getId()));

            //订单状态
            storeOrderItemResponse.setStatusStr(getStatus(storeOrder));
            storeOrderItemResponse.setStatus(storeOrder.getStatus());
            //支付方式
            storeOrderItemResponse.setPayTypeStr(getPayType(storeOrder.getPayType()));

            // 添加订单类型信息
            storeOrderItemResponse.setOrderType(getOrderTypeStr(storeOrder));
            detailResponseList.add(storeOrderItemResponse);
        }
        return detailResponseList;
    }

    /**
     * 获取订单状态
     *
     * @param storeOrder StoreOrder 订单信息
     * @author Mr.Zhang
     * @since 2020-06-12
     */
    private Map<String, String> getStatus(StoreOrder storeOrder) {
        Map<String, String> map = new HashMap<>();
        map.put("key", "");
        map.put("value", "");
        if (null == storeOrder) {
            return map;
        }
        // 未支付
        if (!storeOrder.getPaid() && storeOrder.getStatus() == 0 && storeOrder.getRefundStatus() == 0 && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_UNPAID);
            map.put("value", Constants.ORDER_STATUS_STR_UNPAID);
            return map;
        }
        // 未发货
        if (storeOrder.getPaid() && storeOrder.getStatus() == 0 && storeOrder.getRefundStatus() == 0
//                && storeOrder.getShippingType() == 1
                && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_NOT_SHIPPED);
            map.put("value", Constants.ORDER_STATUS_STR_NOT_SHIPPED);
            return map;
        }
        // 待收货
        if (storeOrder.getPaid() && storeOrder.getStatus() == 1 && storeOrder.getRefundStatus() == 0
//                && storeOrder.getShippingType() == 1
                && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_SPIKE);
            map.put("value", Constants.ORDER_STATUS_STR_SPIKE);
            return map;
        }
        // 待评价
        if (storeOrder.getPaid() && storeOrder.getStatus() == 2 && storeOrder.getRefundStatus() == 0 && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_BARGAIN);
            map.put("value", Constants.ORDER_STATUS_STR_BARGAIN);
            return map;
        }
        // 交易完成
        if (storeOrder.getPaid() && storeOrder.getStatus() == 3 && storeOrder.getRefundStatus() == 0 && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_COMPLETE);
            map.put("value", Constants.ORDER_STATUS_STR_COMPLETE);
            return map;
        }
        // 待核销
        if (storeOrder.getPaid() && storeOrder.getStatus() == 0 && storeOrder.getRefundStatus() == 0
//                && storeOrder.getShippingType() == 2
                && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_TOBE_WRITTEN_OFF);
            map.put("value", Constants.ORDER_STATUS_STR_TOBE_WRITTEN_OFF);
            return map;
        }

        //申请退款
        if (storeOrder.getPaid() && storeOrder.getRefundStatus() == 1 && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_APPLY_REFUNDING);
            map.put("value", Constants.ORDER_STATUS_STR_APPLY_REFUNDING);
            return map;
        }

        //退款中
        if (storeOrder.getPaid() && storeOrder.getRefundStatus() == 3 && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_REFUNDING);
            map.put("value", Constants.ORDER_STATUS_STR_REFUNDING);
            return map;
        }

        //已退款
        if (storeOrder.getPaid() && storeOrder.getRefundStatus() == 2 && !storeOrder.getIsDel() && !storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_REFUNDED);
            map.put("value", Constants.ORDER_STATUS_STR_REFUNDED);
        }

        //已删除
        if (storeOrder.getIsDel() || storeOrder.getIsSystemDel()) {
            map.put("key", Constants.ORDER_STATUS_DELETED);
            map.put("value", Constants.ORDER_STATUS_STR_DELETED);
        }

        return map;
    }

    private String getOrderStatus(StoreOrder storeOrder) {
        if (!storeOrder.getPaid()) {
            return "待支付";
        }
        if (storeOrder.getIsDel() && (!storeOrder.getIsSystemDel())) {
            return "已取消";
        }
        if (storeOrder.getRefundStatus().equals(1)) {
            return "申请退款中";
        }
        if (storeOrder.getRefundStatus().equals(2)) {
            return "已退款";
        }
        if (storeOrder.getRefundStatus().equals(3)) {
            return "退款中";
        }
        if (storeOrder.getStatus().equals(0)) {
            return "待发货";
        }
        if (storeOrder.getStatus().equals(1)) {
            if (!storeOrder.getType().equals(4)) {
                return "待收货";
            } else {
                return "待核销";
            }
        }
        if (storeOrder.getStatus().equals(2)) {
            return "待评价";
        }
        if (storeOrder.getStatus().equals(3)) {
            return "交易完成";
        }
        return "";
    }

    /**
     * 获取支付文字
     *
     * @param payType String 支付方式
     */
    private String getPayType(String payType) {
        switch (payType) {
            case Constants.PAY_TYPE_WE_CHAT:
                return Constants.PAY_TYPE_STR_WE_CHAT;
            case Constants.PAY_TYPE_YUE:
                return Constants.PAY_TYPE_STR_YUE;
            case Constants.PAY_TYPE_ALI_PAY:
                return Constants.PAY_TYPE_STR_ALI_PAY;
            default:
                return Constants.PAY_TYPE_STR_OTHER;
        }
    }

    /**
     * 获取订单类型（前端展示）
     *
     * @param storeOrder 订单
     * @return String
     */
    private String getOrderTypeStr(StoreOrder storeOrder) {
        String orderTypeFormat = "[{}订单]{}";
        String orderType = StrUtil.format(orderTypeFormat, "普通", "");
        // 核销
        if (StrUtil.isNotBlank(storeOrder.getVerifyCode())) {
            orderType = StrUtil.format(orderTypeFormat, "核销", "");
        }

        if (storeOrder.getType().equals(1)) {// 视频订单
            orderType = StrUtil.format(orderTypeFormat, "视频号", "");
        }
        return orderType;
    }

    /**
     * @Description:赠送课程/讲座/展览
     * @Author: chenBing
     * @Date: 2022/11/24
     */
    @Override
    public boolean send(GiveAwayToUserRequest request) {
        List<String> stringList = Arrays.asList(request.getUserIds().split(","));
        List<SendVo> sendVos = new ArrayList<>();
        stringList.forEach(s -> {
            User user = userService.getById(Integer.valueOf(s));
            SendVo sendVo = sendTo(request, user, stringList.size());
            sendVos.add(sendVo);
        });
        LoginUserVo loginUserVo = SecurityUtil.getLoginUserVo();
        SystemAdmin systemAdmin = loginUserVo.getUser();
        Boolean execute = transactionTemplate.execute(e -> {
            sendVos.forEach(sendVo -> {
                StoreOrder order = sendVo.getStoreOrder();
                // TODO: 2022/11/23 保存storeOrder
                save(order);
                StoreOrderInfo orderInfo = sendVo.getStoreOrderInfo();
                StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
                storeOrderStatus.setOid(order.getId());
                storeOrderStatus.setChangeType(Constants.ORDER_STATUS_CACHE_CREATE_ORDER);
                storeOrderStatus.setChangeMessage("订单生成 管理员账号：" + systemAdmin.getAccount());
                storeOrderStatus.setCreateTime(DateUtil.nowDateTime());
                // TODO: 2022/11/23 保存订单详情
                storeOrderInfoService.save(orderInfo);
                // TODO: 2022/11/23 生成订单日志
                storeOrderStatusService.save(storeOrderStatus);
            });
            switch (request.getType()) {
                // TODO: 2022/11/24 课程
                case 0:
                    CourseScheduling courseScheduling = courseSchedulingService.getById(request.getScheduleId());
                    courseScheduling.setInternalLimit(courseScheduling.getInternalLimit() - stringList.size());
                    courseScheduling.setInternalAppointment(courseScheduling.getInternalAppointment() + stringList.size());
                    courseSchedulingService.updateById(courseScheduling);
                    break;
                // TODO: 2022/11/24 讲座
                case 1:
                    TalkScheduling talkScheduling = talkSchedulingService.getById(request.getScheduleId());
                    talkScheduling.setQuota(talkScheduling.getQuota() - stringList.size());
                    talkScheduling.setNumberOfAppointments(talkScheduling.getNumberOfAppointments() + stringList.size());
                    talkSchedulingService.updateById(talkScheduling);
                    break;
                // TODO: 2022/11/24 展览
                case 2:
                    ExhibitionScheduling exhibitionScheduling = exhibitionSchedulingService.getById(request.getScheduleId());
                    exhibitionScheduling.setQuota(exhibitionScheduling.getQuota() - stringList.size());
                    exhibitionScheduling.setNumberOfAppointments(exhibitionScheduling.getNumberOfAppointments() + stringList.size());
                    exhibitionSchedulingService.updateById(exhibitionScheduling);
                    break;
                default:
                    break;
            }
            return Boolean.TRUE;
        });
        if (!execute) {
            throw new VcaException("生成订单失败");
        }
        return true;
    }

    public SendVo sendTo(GiveAwayToUserRequest request, User user, int sendCounts) {
        SendVo sendVo = new SendVo();
        GenerateHelpVo generateHelpVo = new GenerateHelpVo();
        switch (request.getType()) {
            // TODO: 2022/11/24 课程
            case 0:
                generateHelpVo = verifyCourseOfSend(request.getMainId(), request.getScheduleId(), user, sendCounts);
                break;
            // TODO: 2022/11/24 讲座
            case 1:
                generateHelpVo = verifyTalkOfSend(request.getMainId(), request.getScheduleId(), user, sendCounts);
                break;
            // TODO: 2022/11/24 展览
            case 2:
                generateHelpVo = verifyExhibititonOfSend(request.getMainId(), request.getScheduleId(), user, sendCounts);
                break;
            default:
                break;
        }
        String orderNo = VcaUtil.getOrderNo("order");
        // TODO: 2022/11/11 创建订单 storeOrder
        StoreOrder storeOrder = new StoreOrder();
        storeOrder.setUid(generateHelpVo.getUser().getUid());
        storeOrder.setOrderId(orderNo);
        LoginUserVo loginUserVo = SecurityUtil.getLoginUserVo();
        SystemAdmin systemAdmin = loginUserVo.getUser();
        storeOrder.setRealName(ObjectUtil.isNotNull(generateHelpVo.getUser().getNickname()) ? generateHelpVo.getUser().getNickname() : null);
        storeOrder.setUserPhone(ObjectUtil.isNotNull(generateHelpVo.getUser().getPhone()) ? generateHelpVo.getUser().getPhone() : null);
        storeOrder.setTotalNum(1);
        BigDecimal price = BigDecimal.ZERO;
        if (generateHelpVo.getType() == 0) {
            price = getPrice(generateHelpVo.getPriceId().intValue());
        } else {
            price = generateHelpVo.getPriceId();
        }
        storeOrder.setTotalPrice(price);
        storeOrder.setPayPrice(BigDecimal.ZERO);
        storeOrder.setPaid(true);
        storeOrder.setPayType(Constants.PAY_TYPE_BACKEND);
        storeOrder.setPayTime(DateUtil.nowDateTime());
        storeOrder.setCreateTime(DateUtil.nowDateTime());
        storeOrder.setStatus(1);        //未参与
        storeOrder.setProTotalPrice(price);
        storeOrder.setType(generateHelpVo.getType());
        storeOrder.setRefundStatus(0);  //为退款
        storeOrder.setIsDel(false);
        storeOrder.setIsAlterPrice(false);
        storeOrder.setUserType(1);
        // TODO: 2022/11/24 创建订单详情  orderInfo
        StoreOrderInfo orderInfo = new StoreOrderInfo();
        String merOrderNo = VcaUtil.getOrderNo("order");
        orderInfo.setOrderNo(orderNo);
        orderInfo.setMerOrderNo(merOrderNo);
        orderInfo.setMainId(generateHelpVo.getMainId());
        orderInfo.setType(generateHelpVo.getType());
        orderInfo.setCreateTime(DateUtil.nowDateTime());

        orderInfo.setName(generateHelpVo.getName());
        orderInfo.setImage(generateHelpVo.getCoverImage());
        orderInfo.setPrice(price);
        orderInfo.setPayNum(1);
        orderInfo.setWeight(BigDecimal.ZERO);
        orderInfo.setVolume(BigDecimal.ZERO);
        if (generateHelpVo.getType() != 3) {
            orderInfo.setLanguage(getLanguage("",generateHelpVo.getLanguageId()));
        }
        if (generateHelpVo.getAddressId() != 0) {
            orderInfo.setAddress(JSON.toJSONString(getAddressInfoMap("",generateHelpVo.getAddressId())));
        }
        orderInfo.setSchedulingId(generateHelpVo.getScheduled());
        orderInfo.setSchedulingEndTime(generateHelpVo.getScheduledLingEndTime());
        orderInfo.setSchedulingStartTime(generateHelpVo.getScheduledLingStartTime());
        orderInfo.setSchedulingDate(generateHelpVo.getScheduledLingDate());
        orderInfo.setStatus(1);
        orderInfo.setRefundStatus(0);
        orderInfo.setLecturer(generateHelpVo.getUser().getUid());
        orderInfo.setLecturerName(ObjectUtil.isNotNull(generateHelpVo.getUser().getNickname()) ? generateHelpVo.getUser().getNickname() : null);
        orderInfo.setLecturerEmail(ObjectUtil.isNotNull(generateHelpVo.getUser().getEmail()) ? generateHelpVo.getUser().getEmail() : null);
        orderInfo.setLecturerPhone(ObjectUtil.isNotNull(generateHelpVo.getUser().getPhone()) ? generateHelpVo.getUser().getPhone() : null);
        orderInfo.setIsGet(true);

        orderInfo.setInfo(generateHelpVo.getInfo());
        sendVo.setStoreOrder(storeOrder);
        sendVo.setStoreOrderInfo(orderInfo);
        return sendVo;
    }

    /**
     * @Description:赠送展览校验库存
     * @Author: chenBing
     * @Date: 2022/11/24
     */
    private GenerateHelpVo verifyExhibititonOfSend(Long mainId, Long scheduleId, User user, int sendCounts) {
        Exhibition exhibition = exhibitionService.getById(mainId);
        if (exhibition == null) {
            throw new VcaException("未找到当前ID为【" + mainId + "】的讲座信息");
        }
        ExhibitionScheduling exhibitionScheduling = exhibitionSchedulingService.getById(scheduleId);
        if (exhibitionScheduling == null) {
            throw new VcaException("未找到当前讲座排期ID为【" + scheduleId + "】的课程排期信息");
        }
        if (exhibitionScheduling.getQuota() <= 0) {
            throw new VcaException("当前席位已满");
        }

        if (exhibitionScheduling.getQuota() < sendCounts) {
            throw new VcaException("当前席位不足，请重新选择人数");
        }
        //TODO：获取展览提前停止预约时间
//        Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.EXHIBITION_END_ORDER_TIME));
//        Date schedulingDate = DateUtil.strToDate(
//                exhibitionScheduling.getSchedulingDate() + " " + exhibitionScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
//        DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
//        long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
//        if (between >= 0) {
//            throw new VcaException("无法预约当前展览");
//        }
        GenerateHelpVo generateHelpVo = new GenerateHelpVo();
        generateHelpVo.setUser(user);
        generateHelpVo.setPriceId(exhibition.getPrice());
        generateHelpVo.setAddressId(exhibition.getCourseAddressId());
        generateHelpVo.setScheduled(exhibitionScheduling.getId());
        generateHelpVo.setScheduledLingDate(exhibitionScheduling.getSchedulingDate());
        generateHelpVo.setScheduledLingStartTime(exhibitionScheduling.getSchedulingStartTime());
        generateHelpVo.setScheduledLingEndTime(exhibitionScheduling.getSchedulingEndTime());
        generateHelpVo.setMainId(exhibition.getId());
        generateHelpVo.setName(exhibition.getName());
        generateHelpVo.setCoverImage(exhibition.getCover());
        generateHelpVo.setType(Constants.ORDER_TYPE_EXHIBITION);
        generateHelpVo.setLanguageId(null);
        GenerateHelpVo.Info info = new GenerateHelpVo.Info();
        info.setBuyCount(1);
        info.setName(exhibition.getName());
        info.setCoverImage(exhibition.getCover());
        info.setPrice(exhibition.getPrice());
        info.setMainId(exhibition.getId());
        info.setTypeName(exhibition.getCityName());
        info.setTypeLabelColor("#B4B19E");
        info.setCourseAddress(getAddressInfoMap("",exhibition.getCourseAddressId()));
        GenerateHelpVo.Info.Scheduling scheduling = new GenerateHelpVo.Info.Scheduling();
        scheduling.setSchedulingDate(exhibitionScheduling.getSchedulingDate());
        scheduling.setSchedulingStartTime(exhibitionScheduling.getSchedulingStartTime());
        scheduling.setSchedulingEndTime(exhibitionScheduling.getSchedulingEndTime());
        scheduling.setScheduleId(exhibitionScheduling.getId());
        List<GenerateHelpVo.Info.Scheduling> schedulings = new ArrayList<>();
        schedulings.add(scheduling);
        info.setSchedulings(schedulings);
        generateHelpVo.setInfo(JSON.toJSONString(info));
        return generateHelpVo;
    }

    /**
     * @Description:赠送讲座校验库存
     * @Author: chenBing
     * @Date: 2022/11/24
     */
    private GenerateHelpVo verifyTalkOfSend(Long mainId, Long scheduleId, User user, int sendCounts) {
        Talk talk = talkService.getById(mainId);
        if (talk == null) {
            throw new VcaException("未找到当前ID为【" + mainId + "】的讲座信息");
        }
        TalkScheduling talkScheduling = talkSchedulingService.getById(scheduleId);
        if (talkScheduling == null) {
            throw new VcaException("未找到当前讲座排期ID为【" + scheduleId + "】的课程排期信息");
        }
        if (talkScheduling.getQuota() <= 0) {
            throw new VcaException("当前席位已满");
        }

        if (talkScheduling.getQuota() < sendCounts) {
            throw new VcaException("当前席位不足，请重新选择人数");
        }
        //TODO：获取讲座提前停止预约时间
//        Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey("talk_end_order_time"));
//        Date schedulingDate = DateUtil.strToDate(
//                talkScheduling.getSchedulingDate() + " " + talkScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
//        DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
//        long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
//        if (between >= 0) {
//            throw new VcaException("无法预约当前讲座");
//        }
        GenerateHelpVo generateHelpVo = new GenerateHelpVo();
        generateHelpVo.setUser(user);
        generateHelpVo.setPriceId(talk.getPrice());
        generateHelpVo.setAddressId(talk.getAddressId());
        generateHelpVo.setScheduled(talkScheduling.getId());
        generateHelpVo.setScheduledLingDate(talkScheduling.getSchedulingDate());
        generateHelpVo.setScheduledLingStartTime(talkScheduling.getSchedulingStartTime());
        generateHelpVo.setScheduledLingEndTime(talkScheduling.getSchedulingEndTime());
        generateHelpVo.setMainId(talk.getId());
        generateHelpVo.setName(talk.getName());
        generateHelpVo.setCoverImage(talk.getCoverImage());
        generateHelpVo.setType(Constants.ORDER_TYPE_TALK);
        generateHelpVo.setLanguageId(talkScheduling.getCourseLanguageId());
        GenerateHelpVo.Info info = new GenerateHelpVo.Info();
        info.setBuyCount(1);
        info.setName(talk.getName());
        info.setCoverImage(talk.getCoverImage());
        info.setPrice(talk.getPrice());
        info.setMainId(talk.getId());
        info.setTypeName(talk.getTalkType() == 1 ? "线下讲座" : "线上讲座");
        info.setTypeLabelColor("#B4B19E");
        if (talk.getTalkType() == 1) {
            info.setCourseAddress(getAddressInfoMap("",talk.getAddressId()));
        }
        GenerateHelpVo.Info.Scheduling scheduling = new GenerateHelpVo.Info.Scheduling();
        scheduling.setSchedulingDate(talkScheduling.getSchedulingDate());
        scheduling.setSchedulingStartTime(talkScheduling.getSchedulingStartTime());
        scheduling.setSchedulingEndTime(talkScheduling.getSchedulingEndTime());
        scheduling.setScheduleId(talkScheduling.getId());
        scheduling.setLanguage(getLanguage("",talkScheduling.getCourseLanguageId()));
        List<GenerateHelpVo.Info.Scheduling> schedulings = new ArrayList<>();
        schedulings.add(scheduling);
        info.setSchedulings(schedulings);
        generateHelpVo.setInfo(JSON.toJSONString(info));
        return generateHelpVo;
    }

    /**
     * @Description:赠送课程校验库存
     * @Author: chenBing
     * @Date: 2022/11/24
     */
    private GenerateHelpVo verifyCourseOfSend(Long mainId, Long scheduleId, User user, int sendCounts) {
        Course course = courseService.getById(mainId);
        if (course == null) {
            throw new VcaException("未找到当前ID为【" + mainId + "】的课程信息");
        }
        CourseScheduling courseScheduling = courseSchedulingService.getById(scheduleId);
        if (courseScheduling == null) {
            throw new VcaException("未找到当前课程排期ID为【" + scheduleId + "】的课程排期信息");
        }
        if (courseScheduling.getInternalLimit() <= 0) {
            throw new VcaException("当前席位已满");
        }
        if (courseScheduling.getInternalLimit() < sendCounts) {
            throw new VcaException("当前席位不足，请重新选择人数");
        }
        //TODO：获取课程提前停止预约时间
//        Integer courseEndOrderTimeHour = Integer.valueOf(systemConfigService.getValueByKey(Constants.COURSE_END_ORDER_TIME));
//        Date schedulingDate = DateUtil.strToDate(
//                courseScheduling.getSchedulingDate() + " " + courseScheduling.getSchedulingStartTime() + ":00", "yyyy-MM-dd HH:mm:ss");
//        DateTime offset = cn.hutool.core.date.DateUtil.offset(schedulingDate, DateField.HOUR, -courseEndOrderTimeHour);
//        long between = cn.hutool.core.date.DateUtil.between(offset, cn.hutool.core.date.DateUtil.date(), DateUnit.SECOND, false);
//        if (between >= 0) {
//            throw new VcaException("无法预约当前课程");
//        }
        GenerateHelpVo generateHelpVo = new GenerateHelpVo();
        generateHelpVo.setUser(user);
        generateHelpVo.setPriceId(new BigDecimal(course.getCoursePriceId()));
        generateHelpVo.setAddressId(course.getCourseAddressId());
        generateHelpVo.setScheduled(courseScheduling.getId());
        generateHelpVo.setScheduledLingDate(courseScheduling.getSchedulingDate());
        generateHelpVo.setScheduledLingStartTime(courseScheduling.getSchedulingStartTime());
        generateHelpVo.setScheduledLingEndTime(courseScheduling.getSchedulingEndTime());
        generateHelpVo.setMainId(course.getId());
        generateHelpVo.setName(course.getName());
        generateHelpVo.setCoverImage(course.getCover());
        generateHelpVo.setType(Constants.ORDER_TYPE_COURSE);
        generateHelpVo.setLanguageId(courseScheduling.getCourseLanguageId());
        GenerateHelpVo.Info info = new GenerateHelpVo.Info();
        info.setBuyCount(1);
        info.setName(course.getName());
        info.setCoverImage(course.getCover());
        info.setPrice(getPrice(course.getCoursePriceId()));
        info.setMainId(course.getId());
        info.setTypeName(categoryService.getById(course.getCourseTypeId()).getName());
        info.setTypeLabelColor(categoryService.getById(course.getCourseTypeId()).getLabelColor());
        info.setCourseAddress(getAddressInfoMap("",course.getCourseAddressId()));
        GenerateHelpVo.Info.Scheduling scheduling = new GenerateHelpVo.Info.Scheduling();
        scheduling.setSchedulingDate(courseScheduling.getSchedulingDate());
        scheduling.setSchedulingStartTime(courseScheduling.getSchedulingStartTime());
        scheduling.setSchedulingEndTime(courseScheduling.getSchedulingEndTime());
        scheduling.setScheduleId(courseScheduling.getId());
        scheduling.setLanguage(getLanguage("",courseScheduling.getCourseLanguageId()));
        List<GenerateHelpVo.Info.Scheduling> schedulings = new ArrayList<>();
        schedulings.add(scheduling);
        info.setSchedulings(schedulings);
        generateHelpVo.setInfo(JSON.toJSONString(info));
        return generateHelpVo;
    }

    /**
     * @Description:获取价格
     * @Author: chenBing
     * @Date: 2022/11/24
     */
    public BigDecimal getPrice(Integer priceId) {
        HashMap<String, Object> priceMap = systemGroupDataService.getMapByGid(SysGroupDataConstants.GROUP_DATA_ID_CLIENT_COURSE_PRICE, priceId);
        if (priceMap == null) {
            return BigDecimal.valueOf(priceId);
        }
        String coursePrice = String.valueOf(priceMap.get("coursePrice"));
//        BigDecimal price = BigDecimal.valueOf(Integer.parseInt(coursePrice));
        BigDecimal price = new BigDecimal(coursePrice);
        return price;
    }

    public static void main(String[] args) {
        String price = "2000";
        BigDecimal bigDecimal = new BigDecimal(price);
        System.out.println("bigDecimal = " + bigDecimal);
    }

    /**
     * @Description:获取语言ID
     * @Author: chenBing
     * @Date: 2022/11/24
     */
    public String getLanguage(String language,Integer languageId) {
        HashMap<String, Object> courseLanguageMap = systemGroupDataService.getMapByGid(SysGroupDataConstants.GROUP_DATA_ID_CLIENT_COURSE_LANGUAGE, languageId);
        String courseLanguage = "";
        if("en".equals(language)){
            courseLanguage = String.valueOf(courseLanguageMap.get("courseLanguageEn"));
        }else{
            courseLanguage = String.valueOf(courseLanguageMap.get("courseLanguage"));
        }
        return courseLanguage;
    }

    /**
     * @Description:获取课程上课地址
     * @Author: chenBing
     * @Date: 2022/11/9
     */
    @Override
    public HashMap<String, Object> getAddressInfoMap(String language,Integer addressId) {
        HashMap<String, Object> courseAddressMap = systemGroupDataService.getMapByGid(SysGroupDataConstants.GROUP_DATA_ID_CLIENT_COURSE_ADDRESS, addressId);
        Object courseAddress = "";
        Object courseAddressInfo = "";
        Object dest = "";
        if("en".equals(language)){
            courseAddress = courseAddressMap.get("courseAddressEn");
            courseAddressInfo = courseAddressMap.get("courseAddressInfoEn");
            dest = courseAddressMap.get("destEn");
        }else{
            courseAddress = courseAddressMap.get("courseAddress");
            courseAddressInfo = courseAddressMap.get("courseAddressInfo");
            dest = courseAddressMap.get("dest");
        }

        Object lat = courseAddressMap.get("lat");
        Object lon = courseAddressMap.get("lon");

        HashMap<String, Object> courseAddressInfoMap = new HashMap<>();
        courseAddressInfoMap.put("courseAddress", courseAddress);
        courseAddressInfoMap.put("courseAddressInfo", courseAddressInfo);
        courseAddressInfoMap.put("lat", lat);
        courseAddressInfoMap.put("lon", lon);
        courseAddressInfoMap.put("dest", dest);
        return courseAddressInfoMap;
    }

    /**
     * @Description:判断用户是否预约过当前课程的排期
     * @author:chenbing
     * @date 2022/11/28 16:35
     */
    @Override
    public HashMap<String, Object> checkPersonAppointment(User user, Course course, CourseScheduling courseScheduling, Integer orderType, Long coursePackageId) {
        HashMap<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<StoreOrderInfo> lqw = new LambdaQueryWrapper<>();
        if (orderType == 0) {
            lqw.apply("type in (0,1) AND (main_id = " + course.getId() + " OR taoke_about_course_id = " + course.getId() + ")");
        } else {
            lqw.eq(StoreOrderInfo::getType, orderType);
            lqw.eq(StoreOrderInfo::getMainId, coursePackageId);
            lqw.eq(StoreOrderInfo::getTaokeAboutCourseId, course.getId());
        }
        lqw.eq(StoreOrderInfo::getSchedulingId, courseScheduling.getId());
//        lqw.last("AND (( buyer = lecturer = " + user.getUid() + " OR is_get = 0 )  OR (lecturer = " + user.getUid() + " AND is_get = 1))");
        lqw.and(wrapper -> wrapper
                .and(w -> w.eq(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getLecturer, user.getUid()))
                .or(w -> w.eq(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getIsGet, 0)).or()
                .or(w -> w.ne(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getLecturer, user.getUid()).eq(StoreOrderInfo::getIsGet, 1)));
        List<StoreOrderInfo> infoList = storeOrderInfoService.list(lqw);
        if (infoList.size() <= 0) {
            map.put("orderQuantityToBeWrittenOff", 0);
            map.put("completedOrderQuantity", 0);
            map.put("isAppointment", false);
            return map;
        }
        List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
        for (StoreOrderInfo orderInfo : infoList) {
            int count = count(new LambdaQueryWrapper<StoreOrder>().eq(StoreOrder::getPaid, true).eq(StoreOrder::getRefundStatus, 0).eq(StoreOrder::getOrderId, orderInfo.getOrderNo()));
            if (count > 0) {
                storeOrderInfos.add(orderInfo);
            }
        }
        return getCheckPersonAppointment(storeOrderInfos, map, orderType);
    }

    /**
     * @Description:判断用户是否预约过当前课程的排期
     * @author:chenbing
     * @date 2022/11/28 18:50
     */
    @Override
    public HashMap<String, Object> checkPersonAppointmentExhibition(User user, ExhibitionResponse exhibitionResponse, ExhibitionScheduling exhibitionScheduling, Integer orderType) {
        HashMap<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<StoreOrderInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreOrderInfo::getType, orderType);
        lqw.eq(StoreOrderInfo::getMainId, exhibitionResponse.getId());
        lqw.eq(StoreOrderInfo::getSchedulingId, exhibitionScheduling.getId());
//        lqw.last("AND (( buyer = lecturer = " + user.getUid() + " OR is_get = 0 )  OR (lecturer = " + user.getUid() + " AND is_get = 1))");
        lqw.and(wrapper -> wrapper
                .and(w -> w.eq(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getLecturer, user.getUid()))
                .or(w -> w.eq(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getIsGet, 0)).or()
                .or(w -> w.ne(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getLecturer, user.getUid()).eq(StoreOrderInfo::getIsGet, 1)));
        List<StoreOrderInfo> infoList = storeOrderInfoService.list(lqw);
        if (infoList.size() <= 0) {
            map.put("orderQuantityToBeWrittenOff", 0);
            map.put("completedOrderQuantity", 0);
            map.put("isAppointment", false);
            return map;
        }
        List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
        for (StoreOrderInfo orderInfo : infoList) {
            int count = count(new LambdaQueryWrapper<StoreOrder>().eq(StoreOrder::getPaid, true).eq(StoreOrder::getRefundStatus, 0).eq(StoreOrder::getOrderId, orderInfo.getOrderNo()));
            if (count > 0) {
                storeOrderInfos.add(orderInfo);
            }
        }
        return getCheckPersonAppointment(storeOrderInfos, map, orderType);
    }

    @Override
    public HashMap<String, Object> checkPersonAppointmentExhibitionBySchedulingId(User user, ExhibitionResponse exhibitionResponse, List<Long> schedulingIds, Integer orderType) {
        HashMap<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<StoreOrderInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreOrderInfo::getType, orderType);
        lqw.eq(StoreOrderInfo::getMainId, exhibitionResponse.getId());
        lqw.in(StoreOrderInfo::getSchedulingId, schedulingIds);
        lqw.and(wrapper -> wrapper
                .and(w -> w.eq(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getLecturer, user.getUid()))
                .or(w -> w.eq(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getIsGet, 0)).or()
                .or(w -> w.ne(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getLecturer, user.getUid()).eq(StoreOrderInfo::getIsGet, 1)));
        List<StoreOrderInfo> infoList = storeOrderInfoService.list(lqw);
        if (infoList.size() <= 0) {
            map.put("orderQuantityToBeWrittenOff", 0);
            map.put("completedOrderQuantity", 0);
            map.put("isAppointment", false);
            return map;
        }
        List<String> orderNos = infoList.stream().map(StoreOrderInfo::getOrderNo).collect(Collectors.toList());
        List<StoreOrder> orders = list(new LambdaQueryWrapper<StoreOrder>().eq(StoreOrder::getPaid, true).eq(StoreOrder::getRefundStatus, 0).in(StoreOrder::getOrderId, orderNos));
        List<String> orderIds = orders.stream().map(StoreOrder::getOrderId).collect(Collectors.toList());
        HashSet<String> orderIdSet = new HashSet<>(orderIds);
        List<StoreOrderInfo> storeOrderInfos = infoList.stream().filter(info -> orderIdSet.contains(info.getOrderNo())).collect(Collectors.toList());

        return getCheckPersonAppointment(storeOrderInfos, map, orderType);
    }

    /**
     * @Description:判断用户是否预约过当前讲座的排期
     * @author:chenbing
     * @date 2022/11/28 19:04
     */
    @Override
    public HashMap<String, Object> checkPersonAppointmentTalk(User user, Talk talk, TalkScheduling talkScheduling, Integer orderType) {
        HashMap<String, Object> map = new HashMap<>();
        LambdaQueryWrapper<StoreOrderInfo> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreOrderInfo::getType, orderType);
        lqw.eq(StoreOrderInfo::getMainId, talk.getId());
        //todo: 线上讲座不按照排期查询订单，只需要按照讲座id查询订单
        if (talk.getTalkType() == 1) {
            lqw.eq(StoreOrderInfo::getSchedulingId, talkScheduling.getId());
        }
        lqw.and(wrapper -> wrapper
                .and(w -> w.eq(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getLecturer, user.getUid()))
                .or(w -> w.eq(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getIsGet, 0)).or()
                .or(w -> w.ne(StoreOrderInfo::getBuyer, user.getUid()).eq(StoreOrderInfo::getLecturer, user.getUid()).eq(StoreOrderInfo::getIsGet, 1)));
        List<StoreOrderInfo> infoList = storeOrderInfoService.list(lqw);
        if (infoList.size() <= 0) {
            map.put("orderQuantityToBeWrittenOff", 0);
            map.put("completedOrderQuantity", 0);
            map.put("isAppointment", false);
            return map;
        }
        List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
        for (StoreOrderInfo orderInfo : infoList) {
            int count = count(new LambdaQueryWrapper<StoreOrder>().eq(StoreOrder::getPaid, true).eq(StoreOrder::getRefundStatus, 0).eq(StoreOrder::getOrderId, orderInfo.getOrderNo()));
            if (count > 0) {
                storeOrderInfos.add(orderInfo);
            }
        }
        return getCheckPersonAppointment(storeOrderInfos, map, orderType);
    }

    public HashMap<String, Object> getCheckPersonAppointment(List<StoreOrderInfo> orderInfo, HashMap<String, Object> map, Integer orderType) {
        // TODO: 2022/12/1 查询待核销或已完成订单
        if (orderInfo.size() > 0) {
            Integer orderQuantityToBeWrittenOff = 0;
            Integer completedOrderQuantity = 0;
            //新逻辑
//            List<String> orderNos = orderInfo.stream().filter(info -> info.getType() == 1 && orderType == 1).map(StoreOrderInfo::getOrderNo).collect(Collectors.toList());
//            if (orderNos.size() > 0) {
//                List<StoreOrder> orderList = list(new LambdaQueryWrapper<StoreOrder>().eq(StoreOrder::getPaid, true).eq(StoreOrder::getRefundStatus, 0).in(StoreOrder::getOrderId, orderNos));
//                if (orderList.size() > 0) {
//                    Integer orderTwoAndThreeNum = (int) orderList.stream().filter(order -> order.getStatus() == 3 || order.getStatus() == 2).count();
//                    completedOrderQuantity += orderTwoAndThreeNum;
//                    Integer orderOneNum = (int) orderList.stream().filter(order -> order.getStatus() == 1).count();
//                    orderQuantityToBeWrittenOff += orderOneNum;
//                }
//            }
//            Set<String> orderNoSet = new HashSet<>(orderNos);
//            List<StoreOrderInfo> orderInfoList = new ArrayList<>();
//            orderInfoList = orderInfo.stream().filter(info -> !orderNoSet.contains(info.getOrderNo())).collect(Collectors.toList());
//            if (orderInfoList.size() > 0) {
//                //计算oderInfo的status等于2或3的orderInfo数量
//                Integer twoAndThreeNum = (int) orderInfoList.stream().filter(info -> info.getStatus() == 3 || info.getStatus() == 2).count();
//                completedOrderQuantity += twoAndThreeNum;
//                //计算oderInfo的status等于1的orderInfo数量
//                Integer oneNum = (int) orderInfoList.stream().filter(info -> info.getStatus() == 1).count();
//                orderQuantityToBeWrittenOff += oneNum;
//            }
            //旧逻辑
            for (StoreOrderInfo storeOrderInfo : orderInfo) {
                if (storeOrderInfo.getType() == 1 && orderType == 1) {
                    StoreOrder storeOrder = getOne(new LambdaQueryWrapper<StoreOrder>().eq(StoreOrder::getPaid, true).eq(StoreOrder::getRefundStatus, 0).eq(StoreOrder::getOrderId, storeOrderInfo.getOrderNo()));
                    if (storeOrder == null) {
                        continue;
                    }
                    if (storeOrder.getStatus() == 3 || storeOrder.getStatus() == 2) {
                        completedOrderQuantity++;
                    }
                    if (storeOrder.getStatus() == 1) {
                        orderQuantityToBeWrittenOff++;
                    }
                    continue;
                }
                if (storeOrderInfo.getStatus() == 3 || storeOrderInfo.getStatus() == 2) {
                    completedOrderQuantity++;
                }
                if (storeOrderInfo.getStatus() == 1) {
                    orderQuantityToBeWrittenOff++;
                }
            }
            map.put("orderQuantityToBeWrittenOff", orderQuantityToBeWrittenOff);
            map.put("completedOrderQuantity", completedOrderQuantity);
            map.put("isAppointment", orderQuantityToBeWrittenOff + completedOrderQuantity > 0);
        } else {
            map.put("orderQuantityToBeWrittenOff", 0);
            map.put("completedOrderQuantity", 0);
            map.put("isAppointment", false);
        }
        return map;
    }

    /**
     * @Description:领取课程/讲座/展览/套课
     * @author:chenbing
     * @date 2022/12/1 19:18
     */
    @Override
    public boolean get(List<Integer> orderInfoIds) {
        User user = userService.getInfo();
        LambdaQueryWrapper<StoreOrderInfo> lqw = new LambdaQueryWrapper<StoreOrderInfo>().in(StoreOrderInfo::getId, orderInfoIds);
        if (user.getUserRegisterType() == 1) {
            lqw.eq(StoreOrderInfo::getLecturerPhone, user.getPhone());
        }
        if (user.getUserRegisterType() == 2) {
            lqw.eq(StoreOrderInfo::getLecturerEmail, user.getEmail());
        }
        List<StoreOrderInfo> orderInfos = storeOrderInfoService.list(lqw);
        if (orderInfos.size() <= 0) {
            throw new VcaException("当前课程不属于该用户");
        }
        orderInfos.forEach(orderInfo -> {
            orderInfo.setIsGet(true);
            orderInfo.setLecturer(user.getUid());
        });
        return storeOrderInfoService.updateBatchById(orderInfos);
    }

    /**
     * @Description:根据主订单号获取订单
     * @author:chenbing
     * @date 2022/12/2 13:23
     */
    @Override
    public List<StoreOrder> getOrderByMainOrderId(String mainOrderId) {
        LambdaQueryWrapper<StoreOrder> lqw = new LambdaQueryWrapper<>();
        lqw.eq(StoreOrder::getOrderId, mainOrderId);
        lqw.eq(StoreOrder::getIsDel, false);
        lqw.eq(StoreOrder::getPaid, false);
        lqw.eq(StoreOrder::getUserType, 0);
        return list(lqw);
    }

    /**
     * @return
     * @Description:回滚库存
     * @author:chenbing
     * @date 2022/12/30 15:11
     */
    @Override
    public VcaProductStockVo rollBackStock(StoreOrder storeOrder) {
        List<CourseScheduling> courseSchedulingList = new ArrayList<>();
        List<TalkScheduling> talkSchedulingList = new ArrayList<>();
        List<ExhibitionScheduling> exhibitionSchedulingList = new ArrayList<>();
        List<VcaProduct> vcaProducts = new ArrayList<>();
        List<VcaProductAttrValue> vcaProductAttrValues = new ArrayList<>();
        switch (storeOrder.getType()) {
            case 0:
            case 1:
                List<CourseScheduling> courseSchedulings = rollBackStockOfCourse(storeOrder);
                courseSchedulings.forEach(courseScheduling -> {
                    courseSchedulingList.add(courseScheduling);
                });
                break;
            case 2:
                List<TalkScheduling> talkSchedulings = rollBackStockOfTalk(storeOrder);
                talkSchedulings.forEach(talkScheduling -> {
                    talkSchedulingList.add(talkScheduling);
                });
                break;
            case 3:
                List<ExhibitionScheduling> exhibitionSchedulings = rollBackStockOfExhibition(storeOrder);
                exhibitionSchedulings.forEach(exhibitionScheduling -> {
                    exhibitionSchedulingList.add(exhibitionScheduling);
                });
                break;
            case 4:
                VcaProductStockVo vcaProductStockVo1 = rollBackStockOfProduct(storeOrder);
                vcaProductStockVo1.getVcaProducts().forEach(vcaProduct -> {
                    vcaProducts.add(vcaProduct);
                });
                vcaProductStockVo1.getVcaProductAttrValues().forEach(vcaProductAttrValue -> {
                    vcaProductAttrValues.add(vcaProductAttrValue);
                });
                break;
            default:
                break;
        }
        VcaProductStockVo vcaProductStockVo = new VcaProductStockVo();
        vcaProductStockVo.setCourseSchedulingList(courseSchedulingList);
        vcaProductStockVo.setExhibitionSchedulingList(exhibitionSchedulingList);
        vcaProductStockVo.setTalkSchedulingList(talkSchedulingList);
        vcaProductStockVo.setVcaProductAttrValues(vcaProductAttrValues);
        vcaProductStockVo.setVcaProducts(vcaProducts);
        return vcaProductStockVo;
    }

    /**
     * @Description:回滚商品库存
     * @author:chenbing
     * @date 2022/12/30 15:22
     */
    private VcaProductStockVo rollBackStockOfProduct(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<VcaProduct> vcaProducts = new ArrayList<>();
        List<VcaProductAttrValue> vcaProductAttrValues = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            VcaProduct product = vcaProductService.getById(orderInfo.getProductId());
            product.setStock(product.getStock() + orderInfo.getPayNum());
            VcaProductAttrValue productAttrValue = vcaProductAttrValueService.getById(orderInfo.getAttrValueId());
            productAttrValue.setStock(productAttrValue.getStock() + orderInfo.getPayNum());
            if (order.getPaid()) {
                product.setSales(product.getSales() == 0 ? 0 : product.getSales() - orderInfo.getPayNum());
                productAttrValue.setSales(productAttrValue.getSales() == 0 ? 0 : productAttrValue.getSales() - orderInfo.getPayNum());
            }
            vcaProducts.add(product);
            vcaProductAttrValues.add(productAttrValue);
        });
        VcaProductStockVo vcaProductStockVo = new VcaProductStockVo();
        vcaProductStockVo.setVcaProducts(vcaProducts);
        vcaProductStockVo.setVcaProductAttrValues(vcaProductAttrValues);
        return vcaProductStockVo;
    }

    /**
     * @Description:回滚展览排期库存
     * @author:chenbing
     * @date 2022/12/30 15:21
     */
    private List<ExhibitionScheduling> rollBackStockOfExhibition(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<ExhibitionScheduling> exhibitionSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            ExhibitionScheduling exhibitionScheduling = exhibitionSchedulingService.getOne(new LambdaQueryWrapper<ExhibitionScheduling>().eq(ExhibitionScheduling::getExhibitionId, orderInfo.getMainId()).eq(ExhibitionScheduling::getId, orderInfo.getSchedulingId()));
            exhibitionScheduling.setQuota(exhibitionScheduling.getQuota() + orderInfo.getPayNum());
            exhibitionScheduling.setNumberOfAppointments(exhibitionScheduling.getNumberOfAppointments() == 0 ? 0 : exhibitionScheduling.getNumberOfAppointments() - orderInfo.getPayNum());
            exhibitionSchedulings.add(exhibitionScheduling);
        });
        return exhibitionSchedulings;
    }

    /**
     * @Description:回滚讲座排期库存
     * @author:chenbing
     * @date 2022/12/30 15:18
     */
    private List<TalkScheduling> rollBackStockOfTalk(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<TalkScheduling> talkSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            TalkScheduling talkScheduling = talkSchedulingService.getOne(new LambdaQueryWrapper<TalkScheduling>().eq(TalkScheduling::getTalkId, orderInfo.getMainId()).eq(TalkScheduling::getId, orderInfo.getSchedulingId()));
            talkScheduling.setQuota(talkScheduling.getQuota() + orderInfo.getPayNum());
            talkScheduling.setNumberOfAppointments(talkScheduling.getNumberOfAppointments() == 0 ? 0 : talkScheduling.getNumberOfAppointments() - orderInfo.getPayNum());
            talkSchedulings.add(talkScheduling);
        });
        return talkSchedulings;
    }

    /**
     * @Description:回滚课程排期库存
     * @author:chenbing
     * @date 2022/12/30 15:15
     */
    private List<CourseScheduling> rollBackStockOfCourse(StoreOrder order) {
        List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, order.getOrderId()));
        List<CourseScheduling> courseSchedulings = new ArrayList<>();
        orderInfoList.forEach(orderInfo -> {
            LambdaQueryWrapper<CourseScheduling> lqw = new LambdaQueryWrapper<CourseScheduling>().eq(CourseScheduling::getId, orderInfo.getSchedulingId());
            if (Objects.equals(orderInfo.getType(), Constants.ORDER_TYPE_PACKAGE)) {
                lqw.eq(CourseScheduling::getCourseId, orderInfo.getTaokeAboutCourseId());
            } else {
                lqw.eq(CourseScheduling::getCourseId, orderInfo.getMainId());
            }
            CourseScheduling scheduling = courseSchedulingService.getOne(lqw);
            scheduling.setExternalLimit(scheduling.getExternalLimit() + orderInfo.getPayNum());
            scheduling.setExternalAppointment(scheduling.getExternalAppointment() == 0 ? 0 : scheduling.getExternalAppointment() - orderInfo.getPayNum());
            courseSchedulings.add(scheduling);
        });
        return courseSchedulings;
    }

    /**
     * @Description:活动开始通知
     * @author:chenbing
     * @date 2022/12/30 16:40
     */
    @Override
    public void activityStartPushMessage() {
        String redisKey = OrderRedisConstans.ACTIVITY_START_KEY;
        Long size = redisUtil.getListSize(redisKey);
        logger.info("VcaOrderServiceImpl.activityStartPushMessage | size:" + size);
        if (size < 1) {
            return;
        }
        for (int i = 0; i < size; i++) {
            //如果10秒钟拿不到一个数据，那么退出循环
            Object data = redisUtil.getRightPop(redisKey, 10L);
            if (ObjectUtil.isNull(data)) {
                continue;
            }
            try {
                // TODO: 2022/12/30 查询未参与（status=1），已支付（paid=1）未退款（refund_status=0）未删除（is_del=0 is_system_del=0）
                StoreOrder storeOrder = getOne(new LambdaQueryWrapper<StoreOrder>().eq(StoreOrder::getStatus, 1).eq(StoreOrder::getPaid, 1).eq(StoreOrder::getRefundStatus, 0).eq(StoreOrder::getIsDel, 0).eq(StoreOrder::getIsSystemDel, 0)
                        .ne(StoreOrder::getType, 4)
                        .eq(StoreOrder::getOrderId, String.valueOf(data)));
                if (ObjectUtil.isNull(storeOrder)) {
                    logger.error("VcaOrderServiceImpl.activityStartPushMessage | 订单不存在，orderNo: " + storeOrder);
//                    throw new VcaException("订单不存在，orderNo: " + data);
                    return;
                }
                boolean result = activityStarts(storeOrder);
                if (!result) {
                    redisUtil.lPush(redisKey, data);
                }
            } catch (Exception e) {
                e.printStackTrace();
                redisUtil.lPush(redisKey, data);
            }
        }
    }

    private boolean activityStarts(StoreOrder storeOrder) {
        try {
            // TODO: 2022/12/30 获取活动即将开始的已经预约的排期
            String data = cn.hutool.core.date.DateUtil.tomorrow().toString("yyyy-MM-dd");//时间
            List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, storeOrder.getOrderId()).eq(StoreOrderInfo::getIsTip, 0).eq(StoreOrderInfo::getSchedulingDate,data));
            if (orderInfoList.size() <= 0) {
                return Boolean.FALSE;
            }
            Boolean execute = false;
            for (StoreOrderInfo orderInfo : orderInfoList) {
                String schedulingTime = orderInfo.getSchedulingDate() + " " + orderInfo.getSchedulingStartTime() + ":00";
                DateTime schedulingDateTime = cn.hutool.core.date.DateUtil.parse(schedulingTime, Constants.DATE_FORMAT);
//                if (orderInfo.getType() == 2) {
                    Talk talk = talkService.getById(orderInfo.getMainId());
                    if (talk!=null&&talk.getTalkType() == 2) {
//                        String onlineDate = systemConfigService.getValueByKey(Constants.ONLINE_ACTIVITY_START_TIME);
//                        DateTime onlineTime = cn.hutool.core.date.DateUtil.offset(new Date(), DateField.MINUTE, Integer.parseInt(onlineDate));
//                        if (onlineTime.compareTo(schedulingDateTime) >= 0) {
                            // TODO: 2023/1/3 发送消息
                            generateMessageOfActivity(orderInfo, schedulingDateTime, "微信小程序");
                            orderInfo.setIsTip(1);
                            storeOrderInfoService.updateById(orderInfo);
                            return Boolean.TRUE;
//                        }
//                        return Boolean.FALSE;
                    }
//                }
//                if (dateTime.compareTo(schedulingDateTime) >= 0) {
                    PreOrderCommonVo.CourseInfoDetail courseInfoDetail = JSONObject.parseObject(orderInfo.getInfo(), PreOrderCommonVo.CourseInfoDetail.class);
                    String address = null;
                    List<PreOrderCommonVo.CourseInfoDetail.Scheduling> schedulings = courseInfoDetail.getSchedulings();
                    for (PreOrderCommonVo.CourseInfoDetail.Scheduling scheduling : schedulings) {
                        if (Objects.equals(scheduling.getScheduleId(), orderInfo.getSchedulingId())) {
                            HashMap<String, Object> addressMap = scheduling.getCourseAddress();
                            address = String.valueOf(addressMap.get("courseAddress")) + addressMap.get("courseAddressInfo");
                        }
                    }
                    // TODO: 2023/1/3 发送消息
                    generateMessageOfActivity(orderInfo, schedulingDateTime, address);
                    orderInfo.setIsTip(1);
                    storeOrderInfoService.updateById(orderInfo);
                    execute = true;
//                }
            }
            return execute;
        } catch (NumberFormatException e) {
            throw new RuntimeException(e);
        }
    }


    private boolean activityStart(StoreOrder storeOrder) {
        try {
            // TODO: 2022/12/30 获取活动即将开始的已经预约的排期
            String data = systemConfigService.getValueByKey(Constants.ACTIVITY_START_TIME);
            DateTime dateTime = cn.hutool.core.date.DateUtil.offset(new Date(), DateField.MINUTE, Integer.parseInt(data));
            List<StoreOrderInfo> orderInfoList = storeOrderInfoService.list(new LambdaQueryWrapper<StoreOrderInfo>().eq(StoreOrderInfo::getOrderNo, storeOrder.getOrderId()).eq(StoreOrderInfo::getIsTip, 0));
            if (orderInfoList.size() <= 0) {
                return Boolean.TRUE;
            }
            Boolean execute = false;
            for (StoreOrderInfo orderInfo : orderInfoList) {
                String schedulingTime = orderInfo.getSchedulingDate() + " " + orderInfo.getSchedulingStartTime() + ":00";
                DateTime schedulingDateTime = cn.hutool.core.date.DateUtil.parse(schedulingTime, Constants.DATE_FORMAT);
                if (orderInfo.getType() == 2) {
                    Talk talk = talkService.getById(orderInfo.getMainId());
                    if (talk.getTalkType() == 2) {
                        String onlineDate = systemConfigService.getValueByKey(Constants.ONLINE_ACTIVITY_START_TIME);
                        DateTime onlineTime = cn.hutool.core.date.DateUtil.offset(new Date(), DateField.MINUTE, Integer.parseInt(onlineDate));
                        if (onlineTime.compareTo(schedulingDateTime) >= 0) {
                            // TODO: 2023/1/3 发送消息
                            generateMessageOfActivity(orderInfo, schedulingDateTime, "微信小程序");
                            orderInfo.setIsTip(1);
                            storeOrderInfoService.updateById(orderInfo);
                            return Boolean.TRUE;
                        }
                        return Boolean.FALSE;
                    }
                }
                if (dateTime.compareTo(schedulingDateTime) >= 0) {
                    PreOrderCommonVo.CourseInfoDetail courseInfoDetail = JSONObject.parseObject(orderInfo.getInfo(), PreOrderCommonVo.CourseInfoDetail.class);
                    String address = null;
                    List<PreOrderCommonVo.CourseInfoDetail.Scheduling> schedulings = courseInfoDetail.getSchedulings();
                    for (PreOrderCommonVo.CourseInfoDetail.Scheduling scheduling : schedulings) {
                        if (Objects.equals(scheduling.getScheduleId(), orderInfo.getSchedulingId())) {
                            HashMap<String, Object> addressMap = scheduling.getCourseAddress();
                            address = String.valueOf(addressMap.get("courseAddress")) + addressMap.get("courseAddressInfo");
                        }
                    }
                    // TODO: 2023/1/3 发送消息
                    generateMessageOfActivity(orderInfo, schedulingDateTime, address);
                    orderInfo.setIsTip(1);
                    storeOrderInfoService.updateById(orderInfo);
                    execute = true;
                }
            }
            return execute;
        } catch (NumberFormatException e) {
            throw new RuntimeException(e);
        }
    }

    public String choosePackage(Object id, Integer type) {
        String url = "";
        switch (type) {
            case 0:
                url = "pages/course-detail/index?id=" + id;
                break;
            case 1:
                url = "pages/bundlecourse-detail/index?id=" + id;
                break;
            case 2:
                url = "pages/talk-detail/index?id=" + id;
                break;
            case 3:
                url = "pages/exhibition-detail/index?id=" + id;
                break;
            default:
                break;
        }
        return url;
    }


    /**
     * @Description:发送消息
     * @author:chenbing
     * @date 2023/1/3 11:20
     */
    private void generateMessageOfActivity(StoreOrderInfo orderInfo, DateTime schedulingDateTime, String address) {
        SystemNotification paySuccessOfEvent = systemNotificationService.getByMark(OrderRedisConstans.START_ACTIVITY_OF_EVENT);
        String date = cn.hutool.core.date.DateUtil.format(schedulingDateTime, Constants.DATE_FORMAT_STRING);
        if (paySuccessOfEvent.getIsRoutine().equals(1)) {
            // TODO: 2022/12/30 生成小程序订阅消息
            //活动名称{{thing1.DATA}}活动时间{{time2.DATA}}活动地址{{thing3.DATA}}活动状态{{phrase4.DATA}}温馨提示{{thing6.DATA}}
            HashMap<String, String> messageMap = new HashMap<>();
            messageMap.put("thing1", orderInfo.getName());
            messageMap.put("time2", date);
            messageMap.put("thing3", address);
            messageMap.put("phrase4", "即将开始");
            if (orderInfo.getType() == 2) {
                if (talkService.getById(orderInfo.getMainId()).getTalkType() == 2) {
                    messageMap.put("thing3", "微信小程序");
                }
            }
            messageMap.put("thing6", "邀您一同在历峰双子别墅探索新知。");
            generateMessageRoutineCollection(messageMap, orderInfo.getBuyer(), orderInfo.getLecturer(), paySuccessOfEvent.getRoutineId(), choosePackage(orderInfo.getMainId(), orderInfo.getType()));
        }
        if (paySuccessOfEvent.getIsWechat().equals(1)) {
            // TODO: 2023/1/3 公众号模板消息
            HashMap<String, Object> message = new HashMap<>();
            message.put("first", "活动即将开始");
            message.put("keyword1", DateUtil.dateToStr(orderInfo.getCreateTime(), Constants.DATE_FORMAT));
            message.put("keyword2", orderInfo.getName());
            message.put("keyword3", address);
            if (orderInfo.getType() == 2) {
                if (talkService.getById(orderInfo.getMainId()).getTalkType() == 2) {
                    message.put("keyword3", "微信小程序");
                }
            }
            message.put("keyword4", date);
            message.put("remark", "活动即将举行，期待您的光临！");
            generateMessagePublicCollection(message, orderInfo.getBuyer(), orderInfo.getLecturer(), paySuccessOfEvent.getWechatId(), choosePackage(orderInfo.getMainId(), orderInfo.getType()));
        }
        if (paySuccessOfEvent.getIsSms().equals(1)) {
            // TODO: 2023/1/3 发送短信
            SmsTemplate smsTemplate = smsTemplateService.getDetail(paySuccessOfEvent.getSmsId());
            if (Objects.equals(orderInfo.getBuyer(), orderInfo.getLecturer())) {
                smsActivity(orderInfo.getBuyer(), orderInfo.getName(), orderInfo, date, smsTemplate.getTempId());
            } else {
                smsActivity(orderInfo.getBuyer(), orderInfo.getName(), orderInfo, date, smsTemplate.getTempId());
                smsActivity(orderInfo.getLecturer(), orderInfo.getName(), orderInfo, date, smsTemplate.getTempId());
            }
        }
    }

    private void generateMessagePublicCollection(HashMap<String, Object> message, Integer buyer, Integer lecturer, Integer wechatId, String pageUrl) {
        UserToken buyerToken = null;
        if (ObjectUtil.isNotNull(buyer)) {
            buyerToken = userTokenService.getTokenByUserId(buyer, OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
        }
        UserToken lecturerToken = null;
        if (ObjectUtil.isNotNull(lecturer)) {
            lecturerToken = userTokenService.getTokenByUserId(lecturer, OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
        }
        if (Objects.equals(buyer, lecturer)) {
            if (ObjectUtil.isNotNull(buyerToken)) {
                templateMessageService.pushTemplatePublicMessage(pageUrl, wechatId, message, buyerToken.getToken());
            }
        } else {
            if (ObjectUtil.isNotNull(buyerToken)) {
                templateMessageService.pushTemplatePublicMessage(pageUrl, wechatId, message, buyerToken.getToken());
            }
            if (ObjectUtil.isNotNull(lecturerToken)) {
                templateMessageService.pushTemplatePublicMessage(pageUrl, wechatId, message, lecturerToken.getToken());
            }
        }
    }

    /**
     * @Description: 活动开始短信发送
     * @author:chenbing
     * @date 2023/1/4 11:13
     */
    private void smsActivity(Integer userId, String name, StoreOrderInfo orderInfo, String date, String tempId) {
        if (ObjectUtil.isNotNull(userId)) {
            User user = userService.getById(userId);
            if (ObjectUtil.isNotNull(user.getPhone())) {
                smsService.sendActivityStart(name, date, user.getPhone(), tempId, choosePackage(orderInfo.getMainId(), orderInfo.getType()));
            }
        } else {
            smsService.sendActivityStart(name, date, orderInfo.getLecturerPhone(), tempId, choosePackage(orderInfo.getMainId(), orderInfo.getType()));
        }
    }

    /**
     * @Description:生成小程序订阅消息需要发送两个人
     * @author:chenbing
     * @date 2022/12/30 17:19
     */
    @Override
    public void generateMessageRoutineCollection(HashMap<String, String> messageMap, Integer buyer, Integer lecturer, Integer routineId, String pageUrl) {
        UserToken buyerToken = null;
        if (ObjectUtil.isNotNull(buyer)) {
            buyerToken = userTokenService.getTokenByUserId(buyer, OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
        }
        UserToken lecturerToken = null;
        if (ObjectUtil.isNotNull(lecturer)) {
            lecturerToken = userTokenService.getTokenByUserId(lecturer, OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
        }
        if (Objects.equals(buyer, lecturer)) {
            if (ObjectUtil.isNotNull(buyerToken)) {
                templateMessageService.pushMiniTemplateMessage(routineId, messageMap, buyerToken.getToken(), pageUrl);
            }
        } else {
            if (ObjectUtil.isNotNull(buyerToken)) {
                templateMessageService.pushMiniTemplateMessage(routineId, messageMap, buyerToken.getToken(), pageUrl);
            }
            if (ObjectUtil.isNotNull(lecturerToken)) {
                templateMessageService.pushMiniTemplateMessage(routineId, messageMap, lecturerToken.getToken(), pageUrl);
            }
        }
    }

    /**
     * @Description:生成小程序订阅消息需要发送一个人
     * @author:chenbing
     * @date 2023/1/10 18:43
     */
    @Override
    public void generateMessageRoutineSingle(HashMap<String, String> messageMap, Integer userId, Integer routineId, String pageUrl) {
        UserToken userToken = userTokenService.getTokenByUserIdException(userId, OrderRedisConstans.SYSTEM_TYPE_ROUTINE);
        if (userToken != null) {
            templateMessageService.pushMiniTemplateMessage(routineId, messageMap, userToken.getToken(), pageUrl);
        }
    }
}
